funccustomSortString(order, s string)string { val := map[byte]int{} for i, c := range order { val[byte(c)] = i + 1 } t := []byte(s) sort.Slice(t, func(i, j int)bool { return val[t[i]] < val[t[j]] }) returnstring(t) }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13
var customSortString = function(order, s) { const val = newArray(26).fill(0); for (let i = 0; i < order.length; ++i) { val[order[i].charCodeAt() - 'a'.charCodeAt()] = i + 1; } const arr = newArray(s.length).fill(0).map((_, i) => s[i]); arr.sort((c0, c1) => val[c0.charCodeAt() - 'a'.charCodeAt()] - val[c1.charCodeAt() - 'a'.charCodeAt()]) let ans = ''; for (let i = 0; i < s.length; ++i) { ans += arr[i]; } return ans; };
复杂度分析
时间复杂度:O(n \log n + |\Sigma|),其中 n 是字符串 s 的长度,\Sigma 是字符集,在本题中 |\Sigma|=26。
排序的时间复杂度为 O(n \log n);
如果我们使用数组存储权值,数组的大小为 O(|\Sigma|);如果我们使用哈希表存储权值,哈希表的大小与字符串 s 和 order 中出现的字符种类数相同,为叙述方便也可以记为 O(|\Sigma|)。
空间复杂度:O(|\Sigma|)。即为数组或哈希表需要使用的空间。
方法二:计数排序
思路与算法
由于字符集的大小为 26,我们也可以考虑使用计数排序代替普通的排序方法。
我们首先遍历字符串 s,使用数组或哈希表统计每个字符出现的次数。随后遍历字符串 order 中的每个字符 c,如果其在 s 中出现了 k 次,就在答案的末尾添加 k 个 c,并将数组或哈希表中对应的次数置为 0。最后我们遍历一次哈希表,对于所有次数 k 非 0 的键值对 (c, k),在答案的末尾添加 k 个 c 即可。
publicclassSolution { publicstringCustomSortString(string order, string s) { int[] freq = newint[26]; foreach (char ch in s) { ++freq[ch - 'a']; } StringBuilder ans = new StringBuilder(); foreach (char ch in order) { while (freq[ch - 'a'] > 0) { ans.Append(ch); freq[ch - 'a']--; } } for (int i = 0; i < 26; ++i) { while (freq[i] > 0) { ans.Append((char) (i + 'a')); freq[i]--; } } return ans.ToString(); } }
[sol2-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defcustomSortString(self, order: str, s: str) -> str: freq = Counter(s) ans = list() for ch in order: if ch in freq: ans.extend([ch] * freq[ch]) freq[ch] = 0 for (ch, k) in freq.items(): if k > 0: ans.extend([ch] * k) return"".join(ans)
char * customSortString(char * order, char * s) { int freq[26]; memset(freq, 0, sizeof(freq)); for (int i = 0; s[i] != '\0'; i++) { ++freq[s[i] - 'a']; } char *ans = (char *)malloc(sizeof(char) * (strlen(s) + 1)); int pos = 0; for (int i = 0; order[i] != '\0'; i++) { if (freq[order[i] - 'a'] > 0) { for (int j = 0; j < freq[order[i] - 'a']; j++) { ans[pos++] = order[i]; } freq[order[i] - 'a'] = 0; } } for (int i = 0; i < 26; ++i) { if (freq[i] > 0) { for (int j = 0; j < freq[i]; j++) { ans[pos++] = i + 'a'; } } } ans[pos] = '\0'; return ans; }
[sol2-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funccustomSortString(order, s string)string { freq := [26]int{} for _, c := range s { freq[c-'a']++ } t := &strings.Builder{} for _, c := range order { if freq[c-'a'] > 0 { t.WriteString(strings.Repeat(string(c), freq[c-'a'])) freq[c-'a'] = 0 } } for i, k := range freq { if k > 0 { t.WriteString(strings.Repeat(string('a'+i), k)) } } return t.String() }