Brute Froce

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        """
        1. find min len to loop
        2. loop from low bit to high bit and add bits with carry 
        3. for remaining bit in 
        # tc O(N) sc O(N)
        """
        if len(a) <= len(b):
            n = len(a)
            dif = len(b) - len(a)
        else:
            return self.addBinary(b,a)
        res = ['0']*(len(b)+1)
        carry = 0
        for i in range(n-1,-1,-1):
            val = (int(a[i]) + int(b[i+dif]) + carry)% 2
            #print(a[i],b[i+dif],carry,val)
            carry = (int(a[i]) + int(b[i+dif]) + carry)//2
            res[i+dif+1] = str(val) # spare one index more for carry 
            
        
        if dif -1 >=0 :
            for j in range(dif-1,-1,-1):
                #print(f'idx is {j}')
                val = (int(b[j]) + carry)%2
                carry = (int(b[j]) + carry)//2
                res[j+1] = str(val) # spare one index more for carry 
    
        res[0] = str(carry)        
        return str(int("".join(res))) # remove leading zeros

Optimization

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        """
        # tc O(N) sc O(N)
        """
        i,j,carry = len(a)-1,len(b)-1,0
        res = []
        while i >= 0 or j >=0:
            sum = carry
            if i>=0:
                sum += ord(a[i])-ord('0')
                i -= 1
            if j>=0:
                sum += ord(b[j])-ord('0')
                j -= 1
            res.append(str(sum%2))
            carry = sum//2
        # resolve last carry
        if carry != 0:
            res.append(str(carry))
        return ''.join(res[::-1])