Given a string s and an integer k, rearrange s such that the same characters are at least distance k from each other. If it is not possible to rearrange the string, return an empty string "".
Example 1:
**Input:** s = "aabbcc", k = 3
**Output:** "abcabc"
**Explanation:** The same letters are at least a distance of 3 from each other.
Example 2:
**Input:** s = "aaabc", k = 3
**Output:** ""
**Explanation:** It is not possible to rearrange the string.
Example 3:
**Input:** s = "aaadbbcc", k = 2
**Output:** "abacabcd"
**Explanation:** The same letters are at least a distance of 2 from each other.
Constraints:
1 <= s.length <= 3 * 105
s consists of only lowercase English letters.
0 <= k <= s.length
ac: priority queue greedy
classSolution {publicStringrearrangeString(String s,int k) {// Edge casesif (s ==null||s.length() ==0|| k ==0) {return s; }int[] count =newint[26];for (int i =0; i <s.length(); i++) { count[s.charAt(i) -'a']++; }PriorityQueue<Node> q =newPriorityQueue<>((a, b) ->a.count==b.count?a.c-b.c:b.count-a.count);for (int i =0; i <count.length; i++) {if (count[i] ==0) continue;Node node =newNode((char)('a'+ i), count[i]);q.offer(node); }Queue<Node> kBuffer =newLinkedList<>();StringBuilder sb =newStringBuilder();while (!q.isEmpty()) {Node curr =q.poll();sb.append(curr.c);curr.count--;kBuffer.offer(curr); // Add to buffer anyway, because kBuffer size is a time counter.if (kBuffer.size() >= k) {// Node in buffer has wait k time, can join the pool again.Node candidate =kBuffer.poll();if (candidate.count>0) q.offer(candidate); } }returnsb.length() ==s.length() ?sb.toString() :""; }classNode {char c;int count;Node(char c,int count) {this.c= c;this.count= count; } }}/*Intuition: we have a pool of chars to choose from, always choose the most frequent one first.When a char is used, it has to wait k time to join the pool again.O(Nlog26) -> O(N) time, O(N) space*/