Daily LeetCode #6
This question requires excuting many conditions.
The basic idea is:
- use a min pq to allow us retrive the one with largest value
- pq stores
int[]
in form of `(num, int that indicates the letter)' - if there are no two same consecutive letters in
res
, we add current letter and put it back to pq with itsnum - 1
- if there are two same consecutive letters in
res
, we poll the second largest one from pq, and put the original one back after the operations on the second one finish - need to check
pq.isEmpty()
when polling the second one - if the current one polled from pq has
num = 0
, we should stop since even the max one is not available
class Solution {
public String longestDiverseString(int a, int b, int c) {
String res = "";
// use max pq
PriorityQueue<int[]> pq = new PriorityQueue<>((m, n) -> Integer.compare(n[0], m[0]));
// initialize pq
if (a != 0) pq.offer(new int[]{a, 0});
if (b != 0) pq.offer(new int[]{b, 1});
if (c != 0) pq.offer(new int[]{c, 2});
String[] letters = {"a", "b", "c"};
// last: last letter
int last = -1;
// now: current letter
int now = -1;
// n: number of consecutive same letters
int n = 0;
while(!pq.isEmpty()) {
int[] curr = pq.poll();
now = curr[1];
int num = curr[0];
n = (now == last) ? n + 1 : 1;
// n < 3 ensures no three same consecutive letters
if(n < 3) {
if(num > 0) {
res += letters[now];
num--;
last = now;
pq.offer(new int[]{num, now});
// if the current max in pq has num 0, no char can be added to res
} else {
break;
}
} else {
// ensure still have element to poll from pq
if(!pq.isEmpty()) {
// when already have two same consecutive letters, choose the next max
int[] newCurr = pq.poll();
now = newCurr[1];
num = newCurr[0];
if(num > 0) {
res += letters[now];
num--;
last = now;
pq.offer(new int[]{num, now});
} else {
break;
}
// put the first polled one back in pq
pq.offer(curr);
} else {
break;
}
}
}
return res;
}
}
Time Complexity: O(nlogn)
, where n = a + b + c
.
[pq operation is O(logn)
, and we have at most a+b+c
operations]
Space Complexity: O(n)