Longest Happy String

Sanjeev SharmaSanjeev Sharma
2 min read

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

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro