题目 https://leetcode.cn/problems/reorganize-string/
答案 https://www.youtube.com/watch?v=2cUKLq-OAoA
从5:00开始,讲到greedy解法。
从高频次向低频次放置字母,先将字母都放置到奇数位置,如果没空间了,再都放置到偶数位置,这样相同的字符一定不会相邻。。
但是,要首先判断是否有字母出现次数超过一半(向上取整),如果是,则不可能摆成功。
因为,如果字符串长度是偶数,那至多有两种字母各出现一半次数。如果长度是奇数,那至多有一种字母出现n/2 + 1次。所以,只要字母不超过一半,一定能有办法摆放它。
class Solution {
public static class Item {
int ch;
int value;
public Item(int ch, int value) {
this.ch = ch;
this.value = value;
}
}
public String reorganizeString(String s) {
int[] count = new int[26];
for (char c : s.toCharArray()) {
count[c - 'a']++;
}
int limit = (s.length() + 1) / 2;
for (int c : count) {
if (c > limit) {
return "";
}
}
PriorityQueue<Item> q = new PriorityQueue<>((o1, o2) -> o2.value - o1.value);
for (int i = 0; i < 26; i++) {
q.add(new Item(i, count[i]));
}
char[] arr = new char[s.length()];
int idx = 0;
Item cur = q.poll();
for (int i = 0; i < s.length(); i++) {
arr[idx] = (char)(cur.ch + (int)'a');
cur.value--;
if (cur.value == 0) {
cur = q.poll();
}
idx += 2;
if (idx >= s.length()) {
idx = 1;
}
}
return new String(arr);
}
}