Shuffle String
EasyPrompt
You are given a string s and an integer array indices of the same length. The string s will be shuffled such that the character at the ith position moves to indices[i] in the shuffled string.
Return the shuffled string.
Example 1:
indicesExample 2:
indices
Constraints:
s.length == indices.length == n1 <= n <= 100sconsists of only lowercase English letters.0 <= indices[i] < n- All values of
indicesare unique.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach attempts to solve the problem without using extra space for the result, by shuffling the characters and indices in-place. It uses the concept of cyclic sort. We iterate through each position, and if the character at that position is not the one that should be there, we swap it with the character from its correct original position. To keep track of the movements, we also swap the corresponding indices. This process is repeated until every character is in its final correct position.
Algorithm
- Convert the input string
sto a character arraycharArray. - Iterate from
i = 0ton-1. - Inside the loop, use a
whileloop that continues as long asindices[i] != i. This condition means the character currently atcharArray[i]is not in its final correct position. - Let
targetIndex = indices[i]. - Swap the character at
iwith the character attargetIndex. - Swap the index at
iwith the index attargetIndex. - This pair of swaps places one character into its correct final position and updates the
indicesarray to reflect the new state. Thewhileloop continues to resolve the new character that has been moved to positioni. - After the loops complete, the
charArrayis correctly ordered. - Convert the
charArrayback to a string and return it.
Walkthrough
The core idea is to place each character in its correct final position one by one. Since strings are immutable in Java, we first convert the input string s into a character array charArray.
We then iterate through the array from i = 0 to n-1. For each index i, we check if the character at charArray[i] is already in its correct place. The correct place for the character originally at s[i] is indices[i]. We use the indices array to track where each character should go. If indices[i] is not equal to i, it means the character at charArray[i] needs to be moved.
We perform a cycle of swaps. We swap charArray[i] with charArray[indices[i]]. To ensure we don't lose track of the correct positions, we also swap indices[i] with indices[indices[i]]. This process continues in a while loop until indices[i] == i, which signifies that the correct character has been placed at index i.
After the outer loop finishes, all characters will be in their correct shuffled positions within charArray.
class Solution { public String restoreString(String s, int[] indices) { char[] charArray = s.toCharArray(); int n = s.length(); for (int i = 0; i < n; i++) { // While the character at index i is not in its correct place while (indices[i] != i) { int targetIndex = indices[i]; // Swap the characters char tempChar = charArray[i]; charArray[i] = charArray[targetIndex]; charArray[targetIndex] = tempChar; // Swap the indices to reflect the character swap int tempIndex = indices[i]; indices[i] = indices[targetIndex]; indices[targetIndex] = tempIndex; } } return new String(charArray); }}Complexity
Time
O(n). Although there is a nested loop structure (`for` and `while`), each swap operation places at least one element in its correct final position. Since there are `n` elements, the total number of swaps across all iterations is at most `n-1`. Therefore, the total time complexity is linear.
Space
O(n). In Java, strings are immutable, so we must create a character array from the string, which takes `O(n)` space. If the input were a mutable character array, the space complexity would be `O(1)` as the shuffling is done in-place.
Trade-offs
Pros
The algorithm is clever and demonstrates an in-place sorting technique.
Conceptually, it uses O(1) auxiliary space (ignoring the space for the mutable copy of the string).
Cons
More complex to understand and implement compared to the auxiliary array approach.
It modifies the input
indicesarray, which might be an undesirable side effect.In Java, it doesn't offer a space advantage over the simpler method due to string immutability.
This is a straightforward and intuitive approach. We create a new character array to build the result. We iterate through the original string and the indices array. For each character at index i in the original string, we place it at the position indices[i] in our new array. This directly maps each character to its new shuffled position.
Algorithm
- Let
nbe the length of the strings. - Create a new character array
resultof sizen. - Loop for
ifrom0ton-1: - The character
s.charAt(i)should move to the positionindices[i]in the shuffled string. - So, set
result[indices[i]] = s.charAt(i). - After the loop, the
resultarray contains all characters in their correct shuffled order. - Convert the
resultarray to a string and return it.
Walkthrough
This method is the most direct way to solve the problem. The problem states that the character at the i-th position moves to indices[i] in the shuffled string. We can use this rule to build the new string.
First, we create an auxiliary character array, let's call it resultChars, with the same length as the input string s. This array will be used to construct the shuffled string.
Then, we iterate through the input string s and the indices array from i = 0 to n-1. In each iteration, we take the character s.charAt(i) and its target destination indices[i]. We then place this character into our resultChars array at the target index. The assignment looks like this: resultChars[indices[i]] = s.charAt(i).
After the loop has processed all the characters, resultChars will contain the fully shuffled sequence of characters. The final step is to convert this character array back into a string, which is our desired output.
class Solution { public String restoreString(String s, int[] indices) { int n = s.length(); char[] resultChars = new char[n]; for (int i = 0; i < n; i++) { resultChars[indices[i]] = s.charAt(i); } return new String(resultChars); }}Complexity
Time
O(n). We iterate through the string of length `n` once to place the characters. Creating the final string from the character array also takes `O(n)` time.
Space
O(n). We use an auxiliary character array of size `n` to store the result before converting it to a string.
Trade-offs
Pros
Very simple and easy to understand and implement.
Highly efficient with a single pass over the data.
Does not modify the input arrays (
sandindices).
Cons
Requires O(n) extra space, which is the main trade-off for its simplicity.
Solutions
Solution
class Solution {public String restoreString(String s, int[] indices) { int n = s.length(); char[] ans = new char[n]; for (int i = 0; i < n; ++i) { ans[indices[i]] = s.charAt(i); } return String.valueOf(ans); }}/** * @param {string} s * @param {number[]} indices * @return {string} */ var restoreString = function (s, indices) { let rs = []; for (let i = 0; i < s.length; i++) { rs[indices[i]] = s[i]; } return rs.join(""); };class Solution {public: string restoreString(string s, vector<int> &indices) { int n = s.size(); string ans(n, 0); for (int i = 0; i < n; ++i) { ans[indices[i]] = s[i]; } return ans; }};class Solution: def restoreString(self, s: str, indices: List[int]) -> str: ans = [0] * len(s) for i, c in enumerate(s): ans[indices[i]] = c return '' . join(ans)Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.