题目链接:https://leetcode-cn.com/problems/reorganize-string/, 将一个字符串重构得到新的字符串相邻的字母不相同,这道题我想到了使用优先队列,但是思路还是错了,正确的思想是使用贪心算法+优先队列+记录表,首先排除无法构成重构字符串的情况(最多的字母个数不超过(n+1)/ 2), 接着使用vector记录下26个字母的个数,序号即字母的序号,值是字母的个数,使用优先队列将个数大的字母排在前面,这里使用了优先队列的比较详细的构造函数,每次取两个字母,放到结果字符串中,如果记录表中该字符个数不为0,则重新将字母push进优先队列中,循环条件是优先队列的元素个数大于1,循环结束后如果优先队列的元素个数不为0,需要将最后的字母放入结果中,具体代码如下:
class Solution { public: string reorganizeString(string S) { if (S.empty()) { return S; } string result; int max_num = 0; vector<int> counts(26,0); for (auto c : S) { if (c <= 'z' && c >= 'a') { max_num = max(max_num, ++counts[c - 'a']); } } auto s_len = S.length(); if (max_num > s_len - max_num + 1) { return result; } auto cmp = [&](char c1, char c2) { return counts[c1 - 'a'] < counts[c2 - 'a']; }; priority_queue<char, vector<char>, decltype(cmp)> char_queue(cmp); for (int i = 0; i < counts.size(); i++) { if (counts[i] > 0) { char_queue.push('a' + i); } } while (char_queue.size() > 1) { char c1 = char_queue.top(); char_queue.pop(); result += c1; counts[c1 - 'a']--; char c2 = char_queue.top(); char_queue.pop(); result += c2; counts[c2 - 'a']--; if (counts[c1 - 'a'] > 0) { char_queue.push(c1); } if (counts[c2 - 'a'] > 0) { char_queue.push(c2); } } if (char_queue.size() > 0) { result += char_queue.top(); char_queue.pop(); } return result; } };