题目链接: https://leetcode.com/problems/rearrange-string-k-distance-apart/
Given a non-empty string str and an integer k, rearrange the string such that the same characters are at least distance k from each other.
All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string ""
.
Example 1:
str = "aabbcc", k = 3 Result: "abcabc" The same letters are at least distance 3 from each other.
Example 2:
str = "aaabc", k = 3 Answer: "" It is not possible to rearrange the string.
Example 3:
str = "aaadbbcc", k = 2 Answer: "abacabcd" Another possible answer is: "abcabcda" The same letters are at least distance 2 from each other.
思路: 最近新添加的google 的题目都挺让人难受的. 真是很受打击啊! 这是我第二遍最后一题了, 到今天为止leetcode总共349题, 一个月之前刷完第一遍的时候还只有334好像, 一个多月又新加了15道题目. 现在已经六月底了, 进度还是比我预想的慢了很多. 明天开始第三遍吧! 希望我能在七月底之前刷完四遍, 然后去面google. 愿我的努力会有回报!
本题的思路是基于贪心的, 先统计每个字符的数量, 为了让字符排列更紧凑, 借助一个优先队列先排列个数大的字符
1. 如果剩余的字符的数量大于k, 那么就需要在接下来排列k个不同的字符, 并将这k个不同字符个数都-1, 如果在排这k个不同字符的时候发现并没有k个不同字符, 说明是无法得到答案的.
2. 如果剩余的字符数量不到k, 那么就在接下排列剩余个数的不同字符. 方法和上面一样.
在优先队列中存储以(数量+字符)的对, 以k为区间大小排列k个从数量高到低的字符, 然后再重复此过程, 这种贪心的策略可以保证让数量大的最优先排列, 并且使其间隔最小的距离, 否则到后来可能没有足够的空间.
代码如下:
class Solution {
public:
string rearrangeString(string str, int k) {
if(k==0) return str;
int len = str.size();
string result;
map hash;
for(auto ch: str) hash[ch]++;
priority_queue> que;
for(auto val: hash) que.push(make_pair(val.second, val.first));
while(!que.empty())
{
vector> vec;
int cnt = min(k, len);
for(int i =0; i < cnt; i++, len--)
{
if(que.empty()) return "";
auto val = que.top();
que.pop();
result += val.second;
if(--val.first>0) vec.push_back(val);
}
for(auto val: vec) que.push(val);
}
return result;
}
};
参考: https://leetcode.com/discuss/108174/c-unordered_map-priority_queue-solution-using-cache