Problem
You are given two strings order and s. All the words of order
are unique and were sorted in some custom order previously.
Permute the characters of s
so that they match the order that order
was sorted. More specifically, if a character x
occurs before a character y
in order
, then x
should occur before y
in the permuted string.
Return any permutation of s
that satisfies this property.
Examples
Example 1:
Input: order = "cba", s = "abcd"
Output: "cbad"
Explanation:
"a", "b", "c" appear in order, so the order of "a", "b", "c" should be "c", "b", and "a".
Since "d" does not appear in order, it can be at any position in the returned string. "dcba", "cdba", "cbda" are also valid outputs.
Example 2:
Input: order = "cbafg", s = "abcd"
Output: "cbad"
Solution
Method 1 - Sorting
To solve this problem, we need to rearrange the characters of the string s
to follow the order specified in order
. Here is a step-by-step approach to achieve this:
- Create a Mapping: Create a priority map from the custom order string, where each character is assigned an index based on its position in the
order
string. - Count Characters in s: Count the occurrences of each character in
s
. This helps in easily constructing the resultant string based on the sorted order. - Construct the Result: Iterate through the
order
string and add characters to the result based on the count from the previous step. Finally, add any characters froms
that were not present inorder
.
Code
Java
class Solution {
public String customSortString(String order, String s) {
Map<Character, Integer> priorityMap = new HashMap<>();
for (int i = 0; i < order.length(); i++) {
priorityMap.put(order.charAt(i), i);
}
int[] count = new int[26];
for (char ch : s.toCharArray()) {
count[ch - 'a']++;
}
StringBuilder ans = new StringBuilder();
for (char ch : order.toCharArray()) {
while (count[ch - 'a'] > 0) {
ans.append(ch);
count[ch - 'a']--;
}
}
for (char ch = 'a'; ch <= 'z'; ch++) {
while (count[ch - 'a'] > 0) {
ans.append(ch);
count[ch - 'a']--;
}
}
return ans.toString();
}
}
Python
class Solution:
def custom_sort_string(self, order: str, s: str) -> str:
priority_map = {c: i for i, c in enumerate(order)}
count = [0] * 26
for ch in s:
count[ord(ch) - ord('a')] += 1
ans = []
for ch in order:
while count[ord(ch) - ord('a')] > 0:
ans.append(ch)
count[ord(ch) - ord('a')] -= 1
for ch in map(chr, range(97, 123)): # iterate 'a' to 'z'
while count[ord(ch) - ord('a')] > 0:
ans.append(ch)
count[ord(ch) - ord('a')] -= 1
return ''.join(ans)
Complexity
- ⏰ Time complexity:
O(n + m)
wheren
is the length ofs
andm
is the length oforder
. This includes creating the priority map, counting occurrences, and constructing the result. - 🧺 Space complexity:
O(n + m)
for storing the counts of characters and the resultant string.