计数的思想
计数的思想,源自于计数排序。
计数就是把出现过的元素个数进行记录。在集合相关操作中,计数+1表示加入元素,计数-1表示删除元素。
我们在操作过程中,有时要对某些变量进行记录,记录出现的位置,记录上一次的值都是计数的思想。
本题我们采用计数的思想,记录每个字母出现的次数。s的长度为n。出现最多次字母的次数为x。若x > n + 1 >> 1则一定无解。
class Solution { public: string reorganizeString(string s) { vector<int> cnt(26); int n = s.size(); for(int i = 0; i < n; i ++ ) { cnt[s[i] - 'a'] ++ ; } int mx = -1, pos = -1, lim = n + 1 >> 1; for(int i = 0; i < cnt.size(); i ++ ) { if(cnt[i] > mx) { mx = cnt[i]; pos = i; } } if(mx > lim) return ""; //初始化桶,将最多的元素放进去 vector<string> buf(mx); for(int i = 0; i < cnt[pos]; i ++ ) { buf[i] += 'a' + pos; } cnt[pos] = 0; int idx = 0; for(int i = 0; i < 26; i ++ ) { for(int j = 0; j < cnt[i]; j ++ ) { buf[idx] += 'a' + i; idx = (idx + 1) % mx; } } string res; for(int i = 0; i < mx; i ++ ) { res += buf[i]; } return res; } };
class Solution { public: vector<int> rearrangeBarcodes(vector<int>& barcodes) { unordered_map<int, int> cnt; for(auto it: barcodes) { cnt[it] ++ ; } int mx = 0, mxk = -1; for(auto &[k, v]: cnt) { if(v > mx) { mx = v; mxk = k; } } vector<vector<int>> buf(mx, vector<int>()); for(int i = 0; i < mx; i ++ ) buf[i].push_back(mxk); int idx = 0; for(auto &[k, v]: cnt) { if(k == mxk) continue; for(int i = 0; i < v; i ++ ) { buf[idx].push_back(k); idx = (idx + 1) % mx; } } vector<int> res; for(auto &it: buf) { for(auto num: it) { res.push_back(num); } } return res; } };