String Without AAA or BBB

medium greedy string

Problem

Given two integers a and b, return any string that contains exactly a letters 'a' and b letters 'b', and that does not contain either of the substrings "aaa" or "bbb".

Inputa = 4, b = 1
Output"aabaa"
Four 'a' and one 'b', and no run of three identical letters appears.

def str_without_3a3b(a, b):
    res = []
    while a > 0 or b > 0:
        tail = "".join(res[-2:])
        if tail == "aa":
            pick_a = False
        elif tail == "bb":
            pick_a = True
        else:
            pick_a = a >= b
        if pick_a:
            res.append("a"); a -= 1
        else:
            res.append("b"); b -= 1
    return "".join(res)
function strWithout3a3b(a, b) {
  const res = [];
  while (a > 0 || b > 0) {
    const tail = res.slice(-2).join("");
    let pickA;
    if (tail === "aa") pickA = false;
    else if (tail === "bb") pickA = true;
    else pickA = a >= b;
    if (pickA) { res.push("a"); a--; }
    else { res.push("b"); b--; }
  }
  return res.join("");
}
class Solution {
    public String strWithout3a3b(int a, int b) {
        StringBuilder res = new StringBuilder();
        while (a > 0 || b > 0) {
            int n = res.length();
            boolean aa = n >= 2 && res.charAt(n - 1) == 'a' && res.charAt(n - 2) == 'a';
            boolean bb = n >= 2 && res.charAt(n - 1) == 'b' && res.charAt(n - 2) == 'b';
            boolean pickA = aa ? false : (bb ? true : a >= b);
            if (pickA) { res.append('a'); a--; }
            else { res.append('b'); b--; }
        }
        return res.toString();
    }
}
string strWithout3a3b(int a, int b) {
    string res;
    while (a > 0 || b > 0) {
        int n = (int)res.size();
        bool aa = n >= 2 && res[n - 1] == 'a' && res[n - 2] == 'a';
        bool bb = n >= 2 && res[n - 1] == 'b' && res[n - 2] == 'b';
        bool pickA = aa ? false : (bb ? true : a >= b);
        if (pickA) { res += 'a'; a--; }
        else { res += 'b'; b--; }
    }
    return res;
}
Time: O(a + b) Space: O(a + b)