S
and T
are strings composed of lowercase letters. In S
, no letter occurs more than once.
S
was sorted in some custom order previously. We want to permute the characters of T
so that they match the order that S
was sorted. More specifically, if x
occurs before y
in S
, then x
should occur before y
in the returned string.
Return any permutation of T
(as a string) that satisfies this property.
Example : Input: S = "cba" T = "abcd" Output: "cbad" Explanation: "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs.
Note:
S
has length at most26
, and no character is repeated inS
.T
has length at most200
.S
andT
consist of lowercase letters only.
這道題給了我們兩個字符串S和T,讓我們將T按照S的順序進行排序,就是說在S中如果字母x在字母y之前,那么排序后的T中字母x也要在y之前,其他S中未出現的字母位置無所謂。那么我們其實關心的是S中的字母,只要按S中的字母順序遍歷,對於遍歷到的每個字母,如果T中有的話,就先排出來,這樣等S中的字母遍歷完了,再將T中剩下的字母加到后面即可。所以我們先用HashMap統計T中每個字母出現的次數,然后遍歷S中的字母,只要T中有,就將該字母重復其出現次數個,加入結果res中,然后將該字母出現次數重置為0。之后再遍歷一遍HashMap,將T中其他字母加入結果res中即可,參見代碼如下:
解法一:
class Solution { public: string customSortString(string S, string T) { string res = ""; unordered_map<char, int> m; for (char c : T) ++m[c]; for (char c : S) { res += string(m[c], c); m[c] = 0; } for (auto a : m) { res += string(a.second, a.first); } return res; } };
下面這種解法的思路和上面的一樣,只不過這里沒有使用HashMap,而是使用了一個長度為26的數組,因為題目中說了S和T中都是小寫的字母,其他部分沒有啥太大的區別,參見代碼如下:
解法二:
class Solution { public: string customSortString(string S, string T) { string res = ""; vector<int> cnt(26, 0); for (char c : T) ++cnt[c - 'a']; for (char c : S) { while (cnt[c - 'a']-- > 0) res.push_back(c); } for (char c : T) { while (cnt[c - 'a']-- > 0) res.push_back(c); } return res; } };
下面這種方法可以說是簡潔的讓人發指啊,就兩行搞定碉堡了。我們自定義了sort的排序的排序方式,對於字符串T中的任意兩個字母a和b,按照其在S中的順序排序,在S中排前面的在T中也排前面,完全符合題意,所以就能很好的work,參見代碼如下:
解法三:
class Solution { public: string customSortString(string S, string T) { sort(T.begin(), T.end(), [&](char a, char b) {return S.find(a) < S.find(b);}); return T; } };
下面這種解法沒有用到STL中內置的find函數,而是用了HashMap來建立S中每個字母和其出現位置之間的映射,這樣在自定義排序方法的時候,就可以直接從HashMap中取位置了,參見代碼如下:
解法四:
class Solution { public: string customSortString(string S, string T) { unordered_map<char, int> m; for (int i = 0; i < S.size(); ++i) { m[S[i]] = i + 1; } sort(T.begin(), T.end(), [&](char a, char b) {return m[a] < m[b];}); return T; } };
類似題目:
https://leetcode.com/problems/custom-sort-string/solution/
https://leetcode.com/problems/custom-sort-string/discuss/116556/Two-Lines-C++