代码改变世界

767. 重构字符串

2020-12-01 00:46  woshihuangrulin  阅读(78)  评论(0编辑  收藏  举报

题目链接: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;


    }
};