|
| 1 | +### 题目描述 |
| 2 | + |
| 3 | +这是 LeetCode 上的 **[791. 自定义字符串排序](https://leetcode.cn/problems/custom-sort-string/solution/by-ac_oier-ali0/)** ,难度为 **中等**。 |
| 4 | + |
| 5 | +Tag : 「构造」、「模拟」 |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +给定两个字符串 `order` 和 `s` 。`order` 的所有单词都是 唯一 的,并且以前按照一些自定义的顺序排序。 |
| 10 | + |
| 11 | +对 `s` 的字符进行置换,使其与排序的 `order` 相匹配。更具体地说,如果在 `order` 中的字符 `x` 出现字符 `y` 之前,那么在排列后的字符串中, `x` 也应该出现在 `y` 之前。 |
| 12 | + |
| 13 | +返回 满足这个性质的 `s` 的任意排列 。 |
| 14 | + |
| 15 | +示例 1: |
| 16 | +``` |
| 17 | +输入: order = "cba", s = "abcd" |
| 18 | +
|
| 19 | +输出: "cbad" |
| 20 | +
|
| 21 | +解释: |
| 22 | +“a”、“b”、“c”是按顺序出现的,所以“a”、“b”、“c”的顺序应该是“c”、“b”、“a”。 |
| 23 | +因为“d”不是按顺序出现的,所以它可以在返回的字符串中的任何位置。“dcba”、“cdba”、“cbda”也是有效的输出。 |
| 24 | +``` |
| 25 | +示例 2: |
| 26 | +``` |
| 27 | +输入: order = "cbafg", s = "abcd" |
| 28 | +
|
| 29 | +输出: "cbad" |
| 30 | +``` |
| 31 | + |
| 32 | +提示: |
| 33 | +* $1 <= order.length <= 26$ |
| 34 | +* $1 <= s.length <= 200$ |
| 35 | +* `order` 和 `s` 由小写英文字母组成 |
| 36 | +* `order` 中的所有字符都 不同 |
| 37 | + |
| 38 | +--- |
| 39 | + |
| 40 | +### 构造 |
| 41 | + |
| 42 | +根据题意进行模拟即可:起始先使用大小为 $C = 26$ 的数组 `cnts` 对 `s` 的所有字符进行词频统计,随后根据 `order` 的优先级进行构造。 |
| 43 | + |
| 44 | +若字符 `x` 在 `order` 中排于 `y` 前面,则先往答案追加 `cnts[x]` 个字符 `x`,再往答案追加 `cnts[y]` 个字符 `y`,并更新对应词频,最后将仅出现在 `s` 中的字符追加到答案尾部。 |
| 45 | + |
| 46 | +Java 代码: |
| 47 | +```Java |
| 48 | +class Solution { |
| 49 | + public String customSortString(String order, String s) { |
| 50 | + int[] cnts = new int[26]; |
| 51 | + for (char c : s.toCharArray()) cnts[c - 'a']++; |
| 52 | + StringBuilder sb = new StringBuilder(); |
| 53 | + for (char c : order.toCharArray()) { |
| 54 | + while (cnts[c - 'a']-- > 0) sb.append(c); |
| 55 | + } |
| 56 | + for (int i = 0; i < 26; i++) { |
| 57 | + while (cnts[i]-- > 0) sb.append((char)(i + 'a')); |
| 58 | + } |
| 59 | + return sb.toString(); |
| 60 | + } |
| 61 | +} |
| 62 | +``` |
| 63 | +TypeScript 代码: |
| 64 | +```TypeScript |
| 65 | +function customSortString(order: string, s: string): string { |
| 66 | + const cnts = new Array<number>(26).fill(0) |
| 67 | + for (const c of s) cnts[c.charCodeAt(0) - 'a'.charCodeAt(0)]++ |
| 68 | + let ans = '' |
| 69 | + for (const c of order) { |
| 70 | + while (cnts[c.charCodeAt(0) - 'a'.charCodeAt(0)]-- > 0) ans += c |
| 71 | + } |
| 72 | + for (let i = 0; i < 26; i++) { |
| 73 | + while (cnts[i]-- > 0) ans += String.fromCharCode(i + 'a'.charCodeAt(0)); |
| 74 | + } |
| 75 | + return ans |
| 76 | +} |
| 77 | +``` |
| 78 | +Python 代码: |
| 79 | +```Python |
| 80 | +class Solution: |
| 81 | + def customSortString(self, order: str, s: str) -> str: |
| 82 | + cnts = [0] * 26 |
| 83 | + for c in s: |
| 84 | + cnts[ord(c) - ord('a')] += 1 |
| 85 | + ans = '' |
| 86 | + for c in order: |
| 87 | + num = ord(c) - ord('a') |
| 88 | + if cnts[num] > 0: |
| 89 | + ans += c * cnts[num] |
| 90 | + cnts[num] = 0 |
| 91 | + for i in range(26): |
| 92 | + if cnts[i] > 0: |
| 93 | + ans += chr(i + ord('a')) * cnts[i] |
| 94 | + return ans |
| 95 | +``` |
| 96 | +* 时间复杂度:$O(n + m)$ |
| 97 | +* 空间复杂度:$O(C)$,其中 $C = 26$ 为字符集大小 |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +### 最后 |
| 102 | + |
| 103 | +这是我们「刷穿 LeetCode」系列文章的第 `No.791` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 |
| 104 | + |
| 105 | +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 |
| 106 | + |
| 107 | +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 |
| 108 | + |
| 109 | +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 |
| 110 | + |
0 commit comments