[Leetcode] 767. Reorganize String 解题报告

题目

Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same.

If possible, output any possible result.  If not possible, return the empty string.

Example 1:

Input: S = "aab"
Output: "aba"

Example 2:

Input: S = "aaab"
Output: ""

Note:

  • S will consist of lowercase letters and have length in range [1, 500].

思路

我们的思路是:首先建立每个字符到其出现次数的映射,然后建立一个大顶堆。每次都取出大顶堆上的两个元素,然后将其加入结果字符串中。如果这两个元素的剩余出现次数还大于0,则我们将其压入大顶堆中继续循环。这样直到大顶堆为空。

我们最后只需要判断用这种贪心算法得到的结果的最后两个字符是否相同,如果相同,则说明无法返回符合条件的结果;否则直接返回结果。算法的时间复杂度是O(nlogn),空间复杂度是O(n)。

代码

class Solution {
public:
    string reorganizeString(string S) {
        unordered_map<char, int> hash;      // map from char to its appear count
        for (auto c : S) {
            ++hash[c];
        }
        vector<vector<int>> vec;
        for (auto it = hash.begin(); it != hash.end(); ++it) {
            vec.push_back({it->second, it->first});
        }
        make_heap(vec.begin(), vec.end());
        string ret;
        while (!vec.empty()) {
            if (vec.size() == 1) {
                ret.insert(ret.end(), vec[0][0], vec[0][1]);
                vec.pop_back();
            }
            else {
                vector<int> first = vec[0];         // pop the first two chars that appear most
                pop_heap(vec.begin(), vec.end());
                vec.pop_back();
                vector<int> second = vec[0];
                pop_heap(vec.begin(), vec.end());
                vec.pop_back();
                ret.push_back(first[1]), ret.push_back(second[1]);
                if (--first[0] > 0) {               // push the two chars if they have remainings
                    vec.push_back(first);
                    push_heap(vec.begin(), vec.end());
                }
                if (--second[0] > 0) {
                    vec.push_back(second);
                    push_heap(vec.begin(), vec.end());
                }
            }
        }
        int length = ret.length();
        if (length > 2 && ret[length - 1] == ret[length - 2]) {
            return "";
        }
        else {
            return ret;
        }
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值