Longest Happy String
Advertisement
Problem
Given counts a, b, c, construct the longest string where no three consecutive characters are the same.
Key insight: Greedy max-heap. Always pick the most frequent character unless it would create 3 in a row.
Solutions
// C++
string longestDiverseString(int a, int b, int c) {
priority_queue<pair<int,char>> maxH;
if(a)maxH.push({a,'a'}); if(b)maxH.push({b,'b'}); if(c)maxH.push({c,'c'});
string res;
while (!maxH.empty()) {
auto [f1,c1]=maxH.top(); maxH.pop();
int n=res.size();
if(n>=2&&res[n-1]==c1&&res[n-2]==c1){
if(maxH.empty())break;
auto[f2,c2]=maxH.top();maxH.pop();
res+=c2; if(f2>1)maxH.push({f2-1,c2}); maxH.push({f1,c1});
} else { res+=c1; if(f1>1)maxH.push({f1-1,c1}); }
}
return res;
}
// Java
public String longestDiverseString(int a, int b, int c) {
PriorityQueue<int[]> maxH = new PriorityQueue<>((x,y)->y[0]-x[0]);
if(a>0)maxH.offer(new int[]{a,0}); if(b>0)maxH.offer(new int[]{b,1}); if(c>0)maxH.offer(new int[]{c,2});
StringBuilder sb = new StringBuilder();
while(!maxH.isEmpty()){
int[]top=maxH.poll(); int n=sb.length();
if(n>=2&&sb.charAt(n-1)-'a'==top[1]&&sb.charAt(n-2)-'a'==top[1]){
if(maxH.isEmpty())break;
int[]nxt=maxH.poll(); sb.append((char)('a'+nxt[1]));
if(nxt[0]>1)maxH.offer(new int[]{nxt[0]-1,nxt[1]});
maxH.offer(top);
} else { sb.append((char)('a'+top[1])); if(top[0]>1)maxH.offer(new int[]{top[0]-1,top[1]}); }
}
return sb.toString();
}
# Python
import heapq
def longestDiverseString(a, b, c):
heap = [(-a, 'a'), (-b, 'b'), (-c, 'c')]
heapq.heapify(heap)
result = []
while heap:
f1, c1 = heapq.heappop(heap)
if len(result) >= 2 and result[-1] == c1 and result[-2] == c1:
if not heap:
break
f2, c2 = heapq.heappop(heap)
result.append(c2)
if f2 + 1 < 0: heapq.heappush(heap, (f2 + 1, c2))
heapq.heappush(heap, (f1, c1))
else:
result.append(c1)
if f1 + 1 < 0: heapq.heappush(heap, (f1 + 1, c1))
return ''.join(result)
// JavaScript
function longestDiverseString(a, b, c) {
const heap = [[a,'a'],[b,'b'],[c,'c']].filter(x=>x[0]>0).sort((a,b)=>b[0]-a[0]);
const result = [];
while (heap.length) {
const [f1, c1] = heap.shift();
const n = result.length;
if (n >= 2 && result[n-1] === c1 && result[n-2] === c1) {
if (!heap.length) break;
const [f2, c2] = heap.shift();
result.push(c2);
if (f2 > 1) { let p=heap.findIndex(x=>x[0]<=f2-1); if(p===-1)heap.push([f2-1,c2]);else heap.splice(p,0,[f2-1,c2]); }
let p=heap.findIndex(x=>x[0]<=f1); if(p===-1)heap.push([f1,c1]);else heap.splice(p,0,[f1,c1]);
} else {
result.push(c1);
if (f1 > 1) { let p=heap.findIndex(x=>x[0]<=f1-1); if(p===-1)heap.push([f1-1,c1]);else heap.splice(p,0,[f1-1,c1]); }
}
}
return result.join('');
}
Complexity
- Time: O((a+b+c) log 3) = O(n)
- Space: O(1)
Advertisement
← Previous
Maximum Frequency Stack