题目链接
https://leetcode-cn.com/problems/reorganize-string/
题目
给定一个字符串
S
,检查是否能重新排布其中的字母,使得两相邻的字符不同。若可行,输出任意可行的结果。若不可行,返回空字符串。
示例
示例 1:
输入: S = "aab"
输出: "aba"示例 2:
输入: S = "aaab"
输出: ""
注意
S
只包含小写字母并且长度在[1, 500]
区间内。
思路
首先我们先考虑,一个字符串能否通过重新排列,使得两相邻的字符不同。容易想到,我们需要把数量最多的字符两两之间隔开,也就是在整个字符串数量最多的字符之间保证有足够多的其他字符插入进去。例如对于字符串aaab,我们要保证 a-a-a 这样,相邻两个字符之间的-可以被其他字符填充,对于数量最多的字符为3个的情况,至少需要2个其他多余的字符才能保证满足要求,因此,一个字符串能否通过重新排列,使得两相邻的字符不同的条件是:maxN-1>s.size()-maxN,其中maxN表示数量最多的字符的个数,s.size()表示字符串s的长度。
那么,对于不满足要求的字符串直接返回空串即可,对于满足要求的字符串,按照以上思路,将所有相同的字符两两之间进行隔开。题目只要求输出一种符合的结果即可,因此我们首先统计每个字符出现的个数,按照个数从大到小进行排序,然后对这些字符依次隔一进行摆放。首先摆放奇数位再摆放偶数位(先按奇数位摆放是要保证最大的字符分散开,因为一个字符串奇数位的字符个数>=偶数位的字符个数)
C++ Code
class Solution {
public:
static bool cmp(pair<char,int> a, pair<char,int> b){
return a.second > b.second;
}
string reorganizeString(string s) {
unordered_map<char, int> S;
int maxN=0;
for(char ch:s)
{
S[ch]++;
maxN=max(maxN,S[ch]);
}
if(maxN-1>s.size()-maxN) return "";
vector<pair<char,int>> SS (S.begin(), S.end());
sort(SS.begin(),SS.end(),cmp);
string result(s);
int index=0;
for(int i=0;i<SS.size();i++)
{
while(SS[i].second>0)
{
result[index]=SS[i].first;
index+=2;
SS[i].second--;
if(index>=s.size()) index=1;
}
}
return result;
}
};
结果