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