[LeetCode] Sort Characters By Frequency 根據字符出現頻率排序


 

Given a string, sort it in decreasing order based on the frequency of characters.

Example 1:

Input:
"tree"

Output:
"eert"

Explanation:
'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.

 

Example 2:

Input:
"cccaaa"

Output:
"cccaaa"

Explanation:
Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
Note that "cacaca" is incorrect, as the same characters must be together.

 

Example 3:

Input:
"Aabb"

Output:
"bbAa"

Explanation:
"bbaA" is also a valid answer, but "Aabb" is incorrect.
Note that 'A' and 'a' are treated as two different characters.

 

這道題讓我們給一個字符串按照字符出現的頻率來排序,那么毫無疑問肯定要先統計出每個字符出現的個數,那么之后怎么做呢?我們可以利用優先隊列的自動排序的特點,把個數和字符組成pair放到優先隊列里排好序后,再取出來組成結果res即可,參見代碼如下:

 

解法一:

class Solution {
public:
    string frequencySort(string s) {
        string res = "";
        priority_queue<pair<int, char>> q;
        unordered_map<char, int> m;
        for (char c : s) ++m[c];
        for (auto a : m) q.push({a.second, a.first});
        while (!q.empty()) {
            auto t = q.top(); q.pop();
            res.append(t.first, t.second);
        }
        return res;
    }
};

 

我們也可以使用STL自帶的sort來做,關鍵就在於重寫comparator,由於需要使用外部變量,記得中括號中放入&,然后我們將頻率大的返回,注意一定還要處理頻率相等的情況,要不然兩個頻率相等的字符可能穿插着出現在結果res中,這樣是不對的。參見代碼如下:

 

解法二:

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> m;
        for (char c : s) ++m[c];
        sort(s.begin(), s.end(), [&](char& a, char& b){
            return m[a] > m[b] || (m[a] == m[b] && a < b);
        });
        return s;
    }
};

 

我們也可以不使用優先隊列,而是建立一個字符串數組,因為某個字符的出現次數不可能超過s的長度,所以我們將每個字符根據其出現次數放入數組中的對應位置,那么最后我們只要從后往前遍歷數組所有位置,將不為空的位置的字符串加入結果res中即可,參見代碼如下:

 

解法三:

class Solution {
public:
    string frequencySort(string s) {
        string res;
        vector<string> v(s.size() + 1);
        unordered_map<char, int> m;
        for (char c : s) ++m[c];
        for (auto &a : m) {
            v[a.second].append(a.second, a.first);
        }
        for (int i = s.size(); i > 0; --i) {
            if (!v[i].empty()) res.append(v[i]);
        }
        return res;
    }
};

 

類似題目:

Top K Frequent Words

First Unique Character in a String

 

參考資料:

https://leetcode.com/problems/sort-characters-by-frequency/description/

https://leetcode.com/problems/sort-characters-by-frequency/discuss/93404/c-on-solution-without-sort

https://leetcode.com/problems/sort-characters-by-frequency/discuss/93409/concise-c-solution-using-stl-sort

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM