给定一个字符串,要求对其进行重组,使相同的字符不相邻,如果无法满足要求,则返回空串。如字符串“aab”,重组后为“aba”。
分析:先统计每个字符出现的次数,把字符和次数存入HashMap中,对HashMap根据次数进行排序,然后再进行重组:前一半append,后一半间隔插入。(其实也可以不用排序,只需找到出现次数最多的那个字符,先append该字符即可)
public String reorganizeString(String S) {
StringBuilder sb = new StringBuilder();
Map<Character, Integer> map = new HashMap<Character, Integer>();
for(int i = 0; i < S.length(); i++) {
int num = map.getOrDefault(S.charAt(i), 0) + 1;
if(num > Math.ceil((double)S.length() / 2)) return ""; //如果一个字符出现次数大于字符串长度的一半,无解
map.put(S.charAt(i), num);
}
List<Map.Entry<Character, Integer>> list = new LinkedList<Map.Entry<Character, Integer>>(map.entrySet());
Collections.sort(list, (Map.Entry<Character, Integer> e1, Map.Entry<Character, Integer> e2) -> (e2.getValue() - e1.getValue()));
int listIndex = 0, chIndex = 1, i = 0;
while(sb.length() < S.length()) {
if(sb.length() < Math.ceil((double)S.length() / 2)) {
sb.append(list.get(listIndex).getKey());
}
else {
sb.insert(i * 2 + 1, list.get(listIndex).getKey());
i++;
}
if(chIndex < list.get(listIndex).getValue()) {
chIndex ++;
}
else {
listIndex ++;
chIndex = 1;
}
}
return sb.toString();
}