You are on page 1of 2

There are a few ways to solve this problem even though most use similar ideas.

This time we will try a recursive


solution, because it is also helpful to show that there is always a valid permutation.

After some observations we can make some sense of the smaller cases. For example, the result for "D" is
straightforwardly {2,1}, the result for "I" is, also easily, {1,2}. We are forgetting of the smallest case of all, even though
it is not allowed in the constraints, an empty string "" would be the signature of a permutation of size 1, the only
possible such permutation is {1}.

Since we know the results for the smaller cases, we should try to find a way to build the results of the larger cases
using the smaller ones as a base. Our new objective is to find a way to, for example, build the result for "ID" using our
knowledge about "D". We know that "D" should have {2,1} as result, once we care about a new letter (The first "I" in
"ID"), we are worrying about permutations of 3 elements and not just of 2 elements anymore. Basically, to a
permutation of two elements, we must insert a new number. An extra observation to make is that "D" is the signature
of {2,1}, but in the case of a permutation of 3 elements, it may also be the signature of {3,1} or {3,2}. We wish to
append an element, to either {2,1},{3,1} or {3,2} and we must decide between 1, 2 and 3. We cannot append 3 to
{3,1} or {3,2}, it would be an invalid permutation, so, we can only append 3 to {2,1}. But {3,2,1} has signature "DD",
not "ID". We should try appending 2 to {3,1}, or 1 to {3,2} (Note that there is only one permutation for each of the
values we can try to insert), the resulting permutations {2,3,1} and {1,3,2} both have a signature equal to "ID", but we
are also interested in the lexicographically first one, so we will pick {1,3,2}. The result for "ID" is therefore {1,3,2}.

We need a fast way to build the new permutations for each possible value of the first element, using the result for the
smaller signature as a base. Let us now try to build the result for "DID". We know that the lexicographically first
permutation for "ID" is {1,3,2}, we need to form the permutations for each of the four (1,2,3 or 4) elements that we
could put at the beginning of the new permutation. The permutations are : {1,3,2} (for 4), {1,4,3} (for 2), {1,4,2} (for 3)
and {2,4,3} (for 1). The key is to see in this case that the way to generate them using {1,3,2} as a base is to simply
use the picked value X, and increase the values inside the permutation by 1 in case they are >= X. For example, if we
want to use X=2 as the first element, the remaining elements change from {1,3,2} to {1,4,3}. This is akin to merely
sliding the numbers >= X to make space for X in the new permutation. So, for "DID" we have four permutations
available that will have a signature "ID" for the last three elements: {1,2,4,3}, {2,1,4,3}, {3,1,4,2} and {4,1,3,2}. But we
are interested in signature "e;DID" so the first element must be greater than the second, thus {1,2,4,3} is not valid. Of
the three valid permuations we pick the lexicographically first one, therefore the result for signature "DID" is: {2,1,4,3}.

We are only interested in the lexicographically-first valid permutation. For now we can use the current logic to find
them, just try all possible numbers from 1 to n (size of the permutation), generate the left side of the permutation
using the result we found for the suffix of the signature. And of all the n permutations generated, consider only the
valid ones and pick the lexicographically first one. But it is possible to further simplify the problem. To show the idea,
we will consider signature "IDID". We know the result for "DID" (2,1,4,3}, and since we are interested in permutations
of n=5 elements, then we can tell that there will be 5 derivate permutations: {1,3,2,5,4}, {2,3,1,5,4}, {3,2,1,5,4},
{4,2,1,5,3} and {5,2,1,4,3}, note that all of them are valid for ..."DID", so when we want to check for validity we only
need to worry about the first character of the larger signature: "I" . Another thing is that there is only one permutation
for each starting element, so in regards to checking for the lexicographically first permutation, we just need to pick the
smallest valid first element. Therefore, in this case, we need to pick the smallest first element such that the second
element of the permutation will be greater than it (Because the first character of the signature is "I"). That element is
1. Tthe result for "IDID" is then {1,3,2,5,4}. As a rule of thumb, when the first character of the signature is "I" then we
should always pick 1 for the first element of the permutation. It will always be possible to pick 1 because we will
always be able to increment the values for all the elements in the permutation we found for the signature suffix,
including the first element (so it will always be greater than 1) and 1 is the lowest possible value. Therefore, when the
signature begins with "I" and 1 is picked for the first element, the permutation will be the lexicographically first valid
one.

If the rule for signatures that begin with "I" is to always pick 1 for the first element, what should we do for signatures
that begin with "D"? We still need the smallest first element that yields a valid permutation, but this time the first
element must be greater than the second element. Let us give the name next to the permutation that we know is the
result for the suffix of the signature. (For example, if "DDID" is the signature, the suffix is "DID" and its result next =
{2,1,4,3}.). We call the result permutation res. The first element res[0] simply has to be greater than next[0], that way,
when next[0] is moved to the result permutation (as res[1]), it will not be increased, so res[0] will be greater than
res[1]. Therefore, we want the smallest element that is greater than next[0]. Since we are dealing with integers, this
element is (next[0]+1). As a new rule of thumb, when the first character in the signature is "D", always pick
(next[0]+1) for the first element. It will be the smallest valid first element, and it is always possible to do it (if all
elements >= (next[0]+1) in the permutation are incremented, they will all still be <= n).

We can put together both rules together: Since there is always a possible to decision in regards to what element to
pick as the first in the result then there will always be a valid permutation. The decision is simple and only requires us
to know the result next for the suffix of the signature. Once the first element is decided, we can use the result next to
find the values of the remaining elements. All of this is enough to implement a solution. Note that for each instance of
the recurrence, we only need to generate next once (recurse the function on a smaller case), so there is no
branching in the recurrence and the only signatures that are sent to the function are those that are suffixes to the
original one, this means that the function is going to get called O(n) times. In each of the O(n) times the function is
called, we will need a O(n) loop to add the elements in next and increment them accordingly. Therefore, the total time
complexity is O(n2). Finally, the base case, is the smallest signature function: an empty string "" for which we found
the result to be {1}.

public int[] reconstruct(String signature)


{
int n = signature.length() + 1;
if( n == 1) { /* Base case */
// Empty signature, the result is {1}:
return new int[]{1};
}
// declare the res array
int[] res = new int[n];
// recurse to find the next array
// which is the result permutation for the suffix
// of the signature.
int[] next = reconstruct(signature.substring(1));

// Pick the necessary value of res[0]:


res[0] = (signature.charAt(0)=='D') ? (next[0]+1) : 1;

// Place the next values in the result array,


// Values higher than res[0] must be incremented.
for (int i=1; i<n; i++) {
res[i] = next[i-1] + (next[i-1] >= res[0]?1:0);
}
return res;
}
0)

0) "IIIII" Returns: {1, 2, 3, 4, 5, 6 }

1) "DI" Returns: {2, 1, 3 }

There are two permutations with this signature: {3,1,2} and {2,1,3}. You must
return the lexicographically smaller one.

2) "IIIID" Returns: {1, 2, 3, 4, 6, 5 }

3) "DIIDID" Returns: {2, 1, 3, 5, 4, 7, 6 }

You might also like