题目描述:
给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。
若可行,输出任意可行的结果。若不可行,返回空字符串。
示例 1:
输入: S = “aab”
输出: “aba”
示例 2:
输入: S = “aaab”
输出: “”
注意:
S 只包含小写字母并且长度在[1, 500]区间内。
方法1:
主要思路:
(1)先统计各个字符出现的数量,如果出现次数最多的字符的出现次数超过了数量加 一的一半,则说明不能重构,否则可以重构;
(2)重构时,先将统计的字符和对应的出现次数保存在最大堆里面,然后逐个取出字符,在对对应的字符串中间隔位置存储即可;
class Solution {
public:
string reorganizeString(string S) {
unordered_map<int,int> mp;
int count=0;
//统计各个字符出现的次数
for(char& ch:S){
++mp[ch];
count=max(count,mp[ch]);
}
//若是字符的最大频率大于字符串长度加一的一半,则说明不能够重构
if(count>(S.size()+1)/2){
return "";
}
//使用最大堆保存各个字符和对应的频率
priority_queue<pair<int, char>, vector<pair<int, char>>> q;
for(auto& it:mp){
q.push(pair<int,char>(it.second,it.first));
}
string res = S;
int i = 0;
//将最大堆中的字符依次取出,按照其频率,间隔存入结果字符串中
while(!q.empty()){
char c = q.top().second;
int cnt = q.top().first;
q.pop();
while(cnt--){
i = i >= S.size() ? 1 : i;
res[i] = c;
i = i + 2;//间隔存入
}
}
return res;
}
};