LeetCode 767
题目描述
给定一个字符串 s ,检查是否能重新排布其中的字母,使得两相邻的字符不同。
返回 s 的任意可能的重新排列。若不可行,返回空字符串 “” 。
示例 :
示例 1:
输入: s = “aab”
输出: “aba”
示例 2:
输入: s = “aaab”
输出: “”
思路
抽屉原理
- c > n/2上取整,一定无解;
- c <= n/2上取整,一定有解
-当n为奇数,当c > n/2上取整 ,先放偶数位置;
-当c <= n/2, 先放奇数,放满后再放偶数;
代码
class Solution {
//抽屉原理:c > n/2上取整,一定无解
// c <= n/2上取整,一定有解
//情况一:当n为奇数,当c > n/2上取整 ,先放偶数位置;
//情况二:当c <= n/2, 先放奇数,放满后再放偶数
public String reorganizeString(String s) {
int maxc = 0;
HashMap<Character, Integer> cntMap = new HashMap<>();
for (var c : s.toCharArray()) {
cntMap.put(c, cntMap.getOrDefault(c, 0) + 1);
maxc = Math.max(maxc, cntMap.getOrDefault(c, 0));
}
int n = s.length();
if (maxc > (n + 1) / 2) {
return "";
}
char[] res = new char[n];
int i = 1, j = 0;
for (char c = 'a'; c <= 'z'; c ++ ) {
if (cntMap.getOrDefault(c, 0) <= n / 2) {
while (cntMap.getOrDefault(c, 0) > 0 && i < n) {
res[i] = c;
cntMap.put(c, cntMap.getOrDefault(c, 0) - 1);
i += 2;
}
}
while (cntMap.getOrDefault(c, 0) > 0 && j < n) {
res[j] = c;
cntMap.put(c, cntMap.getOrDefault(c, 0) - 1);
j += 2;
}
}
return new String(res);
}
}在这里插入代码片
时间复杂度分析
时间 O(N)空间O(N)
总结
数学思维