358 Rearrange String k Distance Apart
Problem:
Given a non-empty string s and an integer k, rearrange the string such that the same characters are at least distance k from each other.
All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string "".
Example 1:
s = "aabbcc", k = 3
Result: "abcabc"
The same letters are at least distance 3 from each other.
Example 2:
s = "aaabc", k = 3
Answer: ""
It is not possible to rearrange the string.
Example 3:
s = "aaadbbcc", k = 2
Answer: "abacabcd"
Another possible answer is: "abcabcda"
The same letters are at least distance 2 from each other.
Solutions:
public class Solution {
private class Node implements Comparable<Node>{
public char c;
public int count;
public Node(char c, int count) {
this.c = c;
this.count = count;
}
public int compareTo(Node n) {
return n.count - this.count;
}
}
public String rearrangeString(String s, int k) {
PriorityQueue<Node> q = new PriorityQueue<Node>();
int[] valid = new int[26];
int[] count = new int[26];
for (int i = 0; i < s.length() ; i ++) {
count[s.charAt(i) - 'a'] ++;
}
for (int i = 0; i < 26; i ++) {
if (count[i] != 0) {
q.add(new Node((char)(i + 'a'), count[i]));
}
}
StringBuilder sb = new StringBuilder();
int index = 0;
while (!q.isEmpty()) {
Stack<Node> tmp = new Stack<Node>();
while (!q.isEmpty() && index < valid[q.peek().c - 'a']) {
tmp.push(q.poll());
}
if (q.isEmpty()) {
return "";
}
Node n = q.poll();
char c = n.c;
if (n.count > 1) {
q.add(new Node(n.c, n.count - 1));
}
while (!tmp.isEmpty()) {
q.add(tmp.pop());
}
valid[c - 'a'] = index + k;
sb.append(c);
index ++;
}
return sb.toString();
}
}
public class Solution {
public String rearrangeString(String s, int k) {
if (k == 0) {
return s;
}
int[] count = new int[26];
for(int i=0; i < s.length(); i++){
count[s.charAt(i) - 'a'] ++;
}
PriorityQueue<Character> q = new PriorityQueue<Character>(new Comparator<Character>(){
public int compare(Character c1, Character c2){
if (count[c1 - 'a'] != count[c2 - 'a']) {
return count[c2 - 'a'] - count[c1 - 'a'];
}
else {
return c1 - c2;
}
}
});
for (int i = 0; i < 26; i ++) {
if (count[i] != 0) {
q.add((char) (i + 'a'));
}
}
StringBuilder sb = new StringBuilder();
int len = s.length();
while(!q.isEmpty()){
int cnt = Math.min(k, len);
ArrayList<Character> tmp = new ArrayList<Character>();
for(int i=0; i < cnt; i++){
if(q.isEmpty())
return "";
char c = q.poll();
sb.append(c);
count[c - 'a'] --;
if(count[c - 'a'] > 0){
tmp.add(c);
}
len--;
}
for(char c: tmp)
q.add(c);
}
return sb.toString();
}
}