这个使用到了贪心算法,使用优先队列来进行添加字符串。
方法:
- 如果字符串小于二那没有意思,直接退出。
- 创建一个数组记录所有的字母。
- 把出现的次数进行统计,如果最大出现的单词大于数组长度的一半,那么是不可能重构的。
- 创建优先队列,队列的栈顶就是出现最多次数的字母。
- 把字母加入队列,然后进行取值。
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* @author xnl
* @Description:
* @date: 2022/6/6 22:52
*/
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
String str = "zhmyo";
System.out.println(solution.reorganizeString(str));
}
public String reorganizeString(String s) {
// 如果小于二的话,没有重构的必要了
if (s.length() < 2){
return "";
}
// 存放26个单词
int[] counts = new int[26];
int maxCount = 0;
// 把所有出现的单词进行统计,放到数组中去
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
counts[c - 'a']++;
maxCount = Math.max(maxCount, counts[c - 'a']);
}
if (maxCount > (s.length() + 1) / 2){
return "";
}
// 优先队列,贪心就贪心在这里,栈顶取最大出现的数
PriorityQueue<Character> queue = new PriorityQueue<Character>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return counts[o2 - 'a'] - counts[o1 - 'a'];
}
});
// 出现的字符进行入栈
for (char i = 'a'; i <= 'z'; i++){
if (counts[i - 'a'] > 0){
queue.offer(i);
}
}
StringBuilder sb = new StringBuilder();
while (queue.size() > 1){
Character poll1 = queue.poll();
Character poll2 = queue.poll();
sb.append(poll1);
sb.append(poll2);
// 两个单词对应的下标
int index1 = poll1 - 'a', index2 = poll2 - 'a';
// 值取出来了,对应数组的值就需要减一
counts[index1]--;
counts[index2]--;
if (counts[index1] > 0){
queue.offer(poll1);
}
if (counts[index2] > 0){
queue.offer(poll2);
}
}
if (queue.size() > 0){
sb.append(queue.poll());
}
return sb.toString();
}
}