LeetCode 451. Sort Characters By Frequency ***** map按值排序转vector,优先队列,频率当下标
来源:互联网 发布:福特汉姆大学 知乎 编辑:程序博客网 时间:2024/06/07 18:37
一、题目
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.题意:题目很长题意很简单。给定一个字符串,按照字母出现的频率由大到小输出。
注意:后边的举例就是一直在强调的,字符串的题注意事项,字符集的范围,大小写,返回的顺序,空字符。
该题范围就是大小写字母并且大小写有别,对于出现频率次数相同的串返回顺序任意。
思路:1.统计字符串中各个字母出现的频率存储在map中。
2.对map按照频率由大到小排序,这里注意是map中按照值排序。
第一反应是利用stl中提供的sort算法实现,这个想法是好的,不幸的是,sort算法有个限制,利用sort算法只能对序列容器进行排序,就是线性的(如vector,list,deque)。map也是一个集合容器,它里面存储的元素是pair,但是它不是线性存储的(前面提过,像红黑树),所以利用sort不能直接和map结合进行排序。需要将map转为vector。
参考博客:http://www.cnblogs.com/lakeone/p/5599047.html
3.对排序后的map取键并相应的频次-1。
class Solution {public: static bool isless(const pair<char,int> l, const pair<char,int> r) //静态成员函数??? { return l.second > r.second; } string frequencySort(string s) { map<char,int> strMap; for(auto ch:s) { strMap[ch]++; } vector<pair<char, int>> vecMap(strMap.begin(), strMap.end()); //map按值排序 sort(vecMap.begin(), vecMap.end(), isless); string outstr; for (auto temp:vecMap) { while (temp.second) { outstr += temp.first; //map取键 temp.second--; } } return outstr; }};
二、总结。
使用二元谓词的时候必须得用静态成员函数。关于静态成员函数记录两个博客:
http://blog.csdn.net/morewindows/article/details/6721430
http://blog.csdn.net/kerry0071/article/details/25741425/
至于为啥使用静态成员函数,请查看
http://blog.csdn.net/xiaxzhou/article/details/71440464
可以使用lamda表达式也很方便。
sort(vecMap.begin(), vecMap.end(), [](const pair<char, int> l, const pair<char, int> r){return l.second > r.second; }/*isless*/);
三、思路2
思路:一个直观的思路是先统计每个字符的数量,然后将这些字符连同频率放入一个优先队列中,再取出来即可.这种时间复杂度为O(n) + O(m log m),其中n为字符串长度,m为不同字符的个数,在最坏情况下时间复杂度为O(n log n),即所有字符都不一样.
注意优先队列的使用,包含头文件<queue>
string frequencySort(string s) {map<char, int> strMap;for (auto ch : s){strMap[ch]++;}priority_queue<pair<int, char>> priQue;for (auto tempMap:strMap){priQue.push(make_pair(tempMap.second, tempMap.first));}string outstr;while(!priQue.empty()){pair<int, char> temp = priQue.top();outstr.append(temp.first, temp.second);priQue.pop();}return outstr;}
其实我们还有一种可以优化的方法,在统计完字符频率之后利用类似与计数排序的方法,开一个n+1长度大小的数组,将不同的频率字符放到频率的索引处.然后从高到低取得所有字符串.这种方法的好处是在最环情况下依然可以保证时间复杂度为O(n).
string frequencySort(string s) {unordered_map<char, int> freq;vector<string> bucket(s.size() + 1, "");string res;//count frequency of each characterfor (char c : s) freq[c]++;//put character into frequency bucketfor (auto& it : freq) {int n = it.second;char c = it.first;bucket[n].append(n, c); //bucket中加入n个c}//form descending sorted stringfor (int i = s.size(); i > 0; i--) {if (!bucket[i].empty())res.append(bucket[i]);}return res;}
回顾知识点:最小堆
既然出现从大到小打印,那么就有可能是从小到大打印,除了将map转成vector,调用默认的sort函数排序之外,还有就是优先队列是按照最小堆建立的。
对于内置类型的最大堆,最小堆建立方法:
//默认最大堆的建立 打印输出89,67,36,23,12,4,1 vector<int> num = { 4, 23, 67, 12, 1, 36, 89 };priority_queue<int> test1(num.begin(), num.end());while (!test1.empty()){cout << test1.top() << " ";test1.pop();}cout << endl; //最小堆的建立包含<functional>,声明方式的改变,输出1,4,12,23,36,67,89 priority_queue<int, vector<int>, greater<int>> test(num.begin(), num.end());while (!test.empty()){cout << test.top()<<" ";test.pop();}
也可使用multiset<int,greater<int>>,按照key由大到小排序
cout << endl;multiset<int, greater<int>> myset(num.begin(), num.end());for_each(myset.begin(), myset.end(), [](const int& out){cout << out << " "; });
完整的最小堆,从小到大频率输出字符
struct cmp{bool operator()(const pair<int, char>&l, const pair<int, char>&r){return l.first > r.first;}};string frequencySort(string s) {map<char, int> strMap;for (auto ch : s){strMap[ch]++;} //注意定义的方式,同时自定义第三个函数priority_queue<pair<int, char>, vector<pair<int, char>>, cmp> priQue;for (auto tempMap : strMap){priQue.push(make_pair(tempMap.second, tempMap.first));}string outstr;while (!priQue.empty()){pair<int, char> temp = priQue.top();outstr.append(temp.first, temp.second);priQue.pop();}return outstr;return 0;}
- LeetCode 451. Sort Characters By Frequency ***** map按值排序转vector,优先队列,频率当下标
- Leetcode 451. Sort Characters By Frequency 按频率对字符排序 解题报告
- Leetcode 451. Sort Characters By Frequency 按频率对字符排序
- LeetCode 451. Sort Characters By Frequency
- [LeetCode]451. Sort Characters By Frequency
- [leetcode] 451. Sort Characters By Frequency
- [LeetCode]451. Sort Characters By Frequency
- LeetCode笔记:451. Sort Characters By Frequency
- LeetCode 451. Sort Characters By Frequency
- 【LeetCode】 451. Sort Characters By Frequency
- [leetcode]451. Sort Characters By Frequency
- Leetcode 451. Sort Characters By Frequency
- Leetcode 451. Sort Characters By Frequency
- Leetcode-451. Sort Characters By Frequency
- LeetCode 451. Sort Characters By Frequency
- LeetCode 451. Sort Characters By Frequency
- LeetCode OJ 451. Sort Characters By Frequency
- leetcode题解-451. Sort Characters By Frequency
- 杭电1556 Color the ball
- 小白笔记3
- CF
- 从今天开始更新博客
- LinkedList简单实现
- LeetCode 451. Sort Characters By Frequency ***** map按值排序转vector,优先队列,频率当下标
- csv文件导入Mysql
- Android自定义控件-一行代码实现加载对话框
- 剑指offer——像素翻转
- HEVC代码学习9:getInterMergeCandidates函数
- Activity 的生命周期分析
- c++左对齐/右对齐的头文件
- linux 重定向与管道
- java.lang.NoClassDefFoundError: android.support.v7.internal.widget.TintManager 解决办法