Custom Sort String
MediumUpdated: Oct 12, 2025
Practice on:
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 - Counting (Order-based Bucket Sort)
To solve this problem we use a counting/bucket approach: count each character in s, then emit characters in the order specified by order, followed by any leftover characters. This is effectively an order-based bucket sort and is optimal for small fixed alphabets.
- 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
orderstring. - 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
orderstring and add characters to the result based on the count from the previous step. Finally, add any characters fromsthat were not present inorder.
Code
C++
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
string customSortString(string order, string s) {
vector<int> count(26, 0);
for (char c : s) count[c - 'a']++;
string ans;
for (char c : order) {
if (count[c - 'a'] > 0) {
ans += string(count[c - 'a'], c);
count[c - 'a'] = 0;
}
}
for (char c = 'a'; c <= 'z'; ++c) {
if (count[c - 'a'] > 0) ans += string(count[c - 'a'], c);
}
return ans;
}
};
Go
package main
import (
"strings"
)
func customSortString(order string, s string) string {
count := make([]int, 26)
for _, ch := range s {
count[ch-'a']++
}
var sb strings.Builder
for _, ch := range order {
if count[ch-'a'] > 0 {
sb.WriteString(strings.Repeat(string(ch), count[ch-'a']))
count[ch-'a'] = 0
}
}
for ch := 'a'; ch <= 'z'; ch++ {
if count[ch-'a'] > 0 {
sb.WriteString(strings.Repeat(string(ch), count[ch-'a']))
}
}
return sb.String()
}
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();
}
}
Kotlin
class Solution {
fun customSortString(order: String, s: String): String {
val count = IntArray(26)
for (ch in s) count[ch - 'a']++
val sb = StringBuilder()
for (ch in order) {
repeat(count[ch - 'a']) { sb.append(ch) }
count[ch - 'a'] = 0
}
for (ch in 'a'..'z') repeat(count[ch - 'a']) { sb.append(ch) }
return sb.toString()
}
}
Python
from typing import List
class Solution:
def customSortString(self, order: str, s: str) -> str:
count = [0] * 26
for ch in s:
count[ord(ch) - ord('a')] += 1
ans: List[str] = []
for ch in order:
while count[ord(ch) - ord('a')] > 0:
ans.append(ch)
count[ord(ch) - ord('a')] -= 1
for i in range(26):
ch = chr(ord('a') + i)
while count[i] > 0:
ans.append(ch)
count[i] -= 1
return ''.join(ans)
Rust
pub struct Solution;
impl Solution {
pub fn custom_sort_string(order: String, s: String) -> String {
let mut count = vec![0usize; 26];
for b in s.bytes() { count[(b - b'a') as usize] += 1; }
let mut ans = String::new();
for b in order.bytes() {
let idx = (b - b'a') as usize;
for _ in 0..count[idx] { ans.push(b as char); }
count[idx] = 0;
}
for i in 0..26 {
for _ in 0..count[i] { ans.push((b'a' + i as u8) as char); }
}
ans
}
}
Typescript
function customSortString(order: string, s: string): string {
const count: number[] = new Array(26).fill(0);
for (const ch of s) count[ch.charCodeAt(0) - 97]++;
let ans = '';
for (const ch of order) {
ans += ch.repeat(count[ch.charCodeAt(0) - 97]);
count[ch.charCodeAt(0) - 97] = 0;
}
for (let i = 0; i < 26; i++) {
if (count[i] > 0) ans += String.fromCharCode(97 + i).repeat(count[i]);
}
return ans;
};
Complexity
- ⏰ Time complexity:
O(n + m)wherenis the length ofsandmis 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.