题目描述:
给定一个字符串S
,检查是否能重新排布其中的字母,使得两相邻的字符不同。
若可行,输出任意可行的结果。若不可行,返回空字符串。
示例 1:
输入: S = "aab" 输出: "aba"
示例 2:
输入: S = "aaab" 输出: ""
注意:
S
只包含小写字母并且长度在[1, 500]
区间内。
思路:这里使用的方法是使用了优先队列的方法,因为优先队列每次插入一个数据之后是自动排序的,一个最直观的解法是遍历一遍字符串,统计每类字符的频数,然后对字符按照出现的频数从大到小排序(可以做成<频数,字符>的映射,加入优先队列)。然后每次提取出优先队列中的队首的两个映射处理,我们将这两个映射中的字符连在一起,然后还要对其频数-1,如果减了频数以后,频数有依然不为0,,将修改后的映射重新插入优先队列,等待下次排列。
代码:
class Solution {
public:
string reorganizeString(string S) {
int length=int(S.size());
if(length==0)
return "";
if(length==1)
return S;
map<char, int> m;
for(char a:S)
++m[a];
//建立优先队列,按照字符出现次数的顺序排序
int length_mid=(length+1)/2;
priority_queue <pair<int, char> > pq;
for(auto p:m){
if(p.second>length_mid)
return "";
else
pq.push({p.second, p.first});
}
string re="";
pair<int, char> t1;
pair<int, char> t2;
while(pq.size()>1){
t1=pq.top();
pq.pop();
t2=pq.top();
pq.pop();
re.push_back(t1.second);
re.push_back(t2.second);
if(--t1.first>0)
pq.push({t1.first,t1.second});
if(--t2.first>0)
pq.push({t2.first,t2.second});
}
if(pq.size()==1){
t1=pq.top();
if(t1.first>1)
return "";
else{
re.push_back(t1.second);
return re;
}
}
else
return re;
}
};