给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。
若可行,输出任意可行的结果。若不可行,返回空字符串。
示例 1:
输入: S = “aab”
输出: “aba”
示例 2:
输入: S = “aaab”
输出: “”
注意:
S 只包含小写字母并且长度在[1, 500]区间内。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reorganize-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
最开始的想法是用map储存每个字符的数目,然后判断有无超过一半的,超过就说明不满足条件,没有超过就到了构建符合条件的字符串环节,由于map的排序默认按照key,用value的话还要单独写函数,只能是vector的排序,不能真正实现map的排序,只好作罢,参考了一位老哥的代码,真的方法特别秒,最后排序后从小到大的数目插入即可,代码如下:
class Solution {
public:
string reorganizeString(string S) {
int n = S.size();
vector<int> count(26, 0);
for (auto c : S) {
count[c - 'a'] += 100; // 统计次数
if (count[c - 'a'] / 100 > (n + 1) / 2) return ""; // 超过(n+1)/2个字符,不可能得到答案
}
for (int i = 0; i < 26; ++i) count[i] += i; // 将字符信息加入数组值中
// 此时count中的元素存储了次数和字符信息
// 如 count[i] = 203 表示字符 'd'='a'+203%100 出现了 2=203/100 次
sort(count.begin(), count.end()); // 对次数从小到大排序
int index = 1;
string ret(n, ' ');
for (auto c : count) {
int cnt = c / 100; // 取出次数
char ch = 'a' + (c % 100); // 取出字符信息
for (int i = 0; i < cnt; ++i) {
if (index >= n) index = 0; // 第一遍走完 从0开始
ret[index] = ch;
index += 2; // 间隔添加相同字符
}
}
return ret;
}
};