Leetcode 767. 重构字符串
题目
给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。
若可行,输出任意可行的结果。若不可行,返回空字符串。
测试样例
示例 1:
输入: S = "aab"
输出: "aba"
示例 2:
输入: S = "aaab"
输出: ""
注意:
- S 只包含小写字母并且长度在[1, 500]区间内。
题解
优先队列,贪心
我们先统计每个字母出现的次数,每次都选择出现次数最多的字母;但如果上一次选的就是这个字母,则选次多的字母。详细过程见代码
代码
class Word{
public:
char c;
int time;
Word(char c,int time){
this->c = c;
this->time = time;
}
bool operator < (const Word w) const{
return this->time < w.time;
}
};
class Solution {
public:
string reorganizeString(string S) {
unordered_map<char,int> count;
int len = S.length();
for(int i=0; i<len; i++){
count[S[i]]++;
if(count[S[i]] > (len+1)/2) return ""; //如果有一个字母出现次数超过字符串长度的一半,则直接返回空串
}
priority_queue<Word> pq;
unordered_map<char,int>::iterator iter = count.begin();
while(iter != count.end()){
pq.push(Word((*iter).first,(*iter).second));
iter++;
}
Word w = pq.top();
pq.pop();
string ans;
ans = w.c;
w.time--;
if(w.time != 0)
pq.push(w);
while(!pq.empty()){
Word most = pq.top();
pq.pop();
if(ans.back() != most.c){ //出现次数最多的字母并没有被上次选择,故本次可以选择
ans += most.c;
most.time--;
if(most.time != 0)
pq.push(most);
}else{ 出现次数最多的字母被上次选择,故本次选择次多的字母
if(pq.empty()) return "";
Word more = pq.top();
pq.pop();
ans += more.c;
more.time--;
if(more.time != 0)
pq.push(more);
pq.push(most);
}
}
return ans;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reorganize-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。