67. Add Binary - Explanation

Problem Link

Description

You are given two binary strings a and b, return their sum as a binary string.

Example 1:

Input: a = "101", b = "10"

Output: "111"

Example 2:

Input: a = "10010", b = "111"

Output: "11001"

Constraints:

  • 1 <= a.length, b.length <= 10,000
  • a and b consist only of '0' or '1' characters.
  • Each string does not contain leading zeros except for the zero itself.


Topics

Company Tags

Please upgrade to NeetCode Pro to view company tags.



Prerequisites

Before attempting this problem, you should be comfortable with:

  • Binary Number System - Understanding how binary addition works with carry propagation
  • String Manipulation - Iterating through strings, reversing, and building result strings character by character
  • Two Pointers - Using two pointers to traverse strings of different lengths simultaneously from the end

1. Iteration

Intuition

Adding binary numbers works just like adding decimal numbers by hand, except we only have digits 0 and 1. We start from the rightmost digits (least significant bits) and add corresponding digits along with any carry from the previous position. If the sum is 2 or more, we carry 1 to the next position. We reverse both strings first to make indexing from the right easier, then build the result and reverse it at the end.

Algorithm

  1. Reverse both input strings for easier right-to-left processing.
  2. Initialize carry = 0 and an empty result string.
  3. For each position from 0 to the maximum length of the two strings:
    • Get the digit from each string (0 if past the string's length).
    • Calculate total = digitA + digitB + carry.
    • Append total % 2 to the result.
    • Update carry = total / 2.
  4. If carry remains, append "1".
  5. Reverse the result string and return.
class Solution:
    def addBinary(self, a: str, b: str) -> str:
        res = ""
        carry = 0

        a, b = a[::-1], b[::-1]
        for i in range(max(len(a), len(b))):
            digitA = ord(a[i]) - ord("0") if i < len(a) else 0
            digitB = ord(b[i]) - ord("0") if i < len(b) else 0

            total = digitA + digitB + carry
            char = str(total % 2)
            res = char + res
            carry = total // 2

        if carry:
            res = "1" + res

        return res

Time & Space Complexity

  • Time complexity: O(max(m,n))O(max(m, n))
  • Space complexity: O(m+n)O(m + n)

Where mm and nn are the lengths of the strings aa and bb respectively.


2. Iteration (Optimal)

Intuition

Instead of reversing the strings upfront, we can use two pointers starting at the end of each string and work backward. This avoids the extra space and time needed to reverse the input strings. We continue until both pointers have moved past the beginning of their strings and no carry remains. The result is built in reverse order, so we reverse it once at the end.

Algorithm

  1. Initialize pointers i and j at the last index of strings a and b.
  2. Initialize carry = 0 and an empty result list.
  3. While i >= 0 or j >= 0 or carry > 0:
    • Get the digit at position i in a (0 if i < 0).
    • Get the digit at position j in b (0 if j < 0).
    • Calculate total = digitA + digitB + carry.
    • Append total % 2 to the result.
    • Update carry = total / 2.
    • Decrement both i and j.
  4. Reverse the result and return as a string.
class Solution:
    def addBinary(self, a: str, b: str) -> str:
        res = []
        carry = 0

        i, j = len(a) - 1, len(b) - 1
        while i >= 0 or j >= 0 or carry > 0:
            digitA = int(a[i]) if i >= 0 else 0
            digitB = int(b[j]) if j >= 0 else 0

            total = digitA + digitB + carry
            res.append(total % 2)
            carry = total // 2

            i -= 1
            j -= 1

        res.reverse()
        return ''.join(map(str, res))

Time & Space Complexity

  • Time complexity: O(max(m,n))O(max(m, n))
  • Space complexity: O(max(m,n))O(max(m, n))

Where mm and nn are the lengths of the strings aa and bb respectively.


Common Pitfalls

Forgetting the Final Carry

After processing all digits, there may still be a carry of 1 that needs to be added to the result. Forgetting to check for this will produce incorrect results for cases like "1" + "1" = "10".

# Wrong: missing final carry check
return ''.join(res)
# Correct: handle remaining carry
if carry:
    res.append('1')
return ''.join(res)

Processing Strings in Wrong Direction

Binary addition must process digits from right to left (least significant to most significant). A common mistake is iterating from the start of the strings instead of the end, which produces completely wrong results.