LeetCode #67 Easy

Add Binary

Add Binary: given two binary strings a and b, return their sum as a binary string. The inputs can be far longer than any integer type can hold.

Constraints
  • 1 <= a.length, b.length <= 10⁴
  • a and b consist only of '0' or '1' characters
  • Each string does not contain leading zeros except for the zero itself
mathstringbit manipulationsimulation
Open on LeetCode ↗
Add Binary diagramA labelled diagram of the structure this problem turns on.add column by column, right to left — never convert to an integercarry111a1010b1011sum10101each column tops out at 1 + 1 + 1 = 3, so the carry is always 0 or 1the leftmost carry adds a digit — dropping it turns "1" + "1" into "0"
02

Intuition

Column addition is the same in base 2 as in base 10 — walk both strings from the right, add the two digits and the carry, write sum % 2, and carry sum // 2. The only base-2 specialisation is that a column can reach 3, so the carry is still at most 1. Converting to an integer first is tempting and wrong: the constraints allow 10⁴ digits, far beyond a 64-bit type.

How to spot this pattern

Digit-by-digit simulation is the move whenever the inputs are given as strings or lists and are explicitly allowed to exceed integer range. The tell is a length constraint far past 19 digits. Add Two Numbers, Plus One, and Multiply Strings are the same column arithmetic.

03

Approach

Try it first

Before reading on: work out the largest value a single column can produce, and convince yourself the carry never exceeds 1. Then check what your code returns for "1" + "1" — the case where the answer is longer than either input.

1

Why the strings cannot be converted to integers

The natural-looking int(a, 2) + int(b, 2) works in Python, whose integers are arbitrary precision, but it is not the intended solution and it fails outright in C++ and Java, where 10⁴ binary digits overflow every primitive type by a factor of about 10³⁰⁰⁰. Even in Python it hides the algorithm the question is asking for. Treating the strings as digit sequences keeps the method identical in all three languages and independent of the word size.

2

One loop over both strings, right to left

Index from the end with a single pointer i counting down, and read a[len(a)-1-i] when that index exists, otherwise 0. This lets one loop handle unequal lengths without padding the shorter string first. At each step compute total = digit_a + digit_b + carry; append total % 2 to the result and set carry = total // 2. Because each digit is 0 or 1, total ranges over 0..3, so the carry is always 0 or 1 — the same invariant that makes decimal column addition work.

3

The final carry and the reversal

After the loop, a carry may remain — adding 1 and 1 produces 10, which is one digit longer than either input. Appending that final carry is what most incorrect solutions forget, and it only shows up on inputs whose sum gains a digit. Because digits were appended least-significant-first, the accumulated list must be reversed before joining. Building a list and reversing once is O(n); repeatedly prepending to a string would copy the whole result each time and degrade to O(n²).

04

Solution & live demo

1class Solution:
2 def addBinary(self, a, b):
3 result = []
4 carry = 0
5 i, j = len(a) - 1, len(b) - 1
6 while i >= 0 or j >= 0 or carry:
7 total = carry
8 if i >= 0:
9 total += int(a[i])
10 i -= 1
11 if j >= 0:
12 total += int(b[j])
13 j -= 1
14 result.append(str(total % 2))
15 carry = total // 2
16 return "".join(reversed(result))
05

Common pitfalls

Converting to integers first

✗ Wrong
return bin(int(a, 2) + int(b, 2))[2:]
✓ Right
add the digits column by column

With up to 10⁴ binary digits the value exceeds every fixed-width integer type, so this cannot be translated to C++ or Java at all. It also sidesteps the algorithm the question exists to test.

Dropping the final carry

✗ Wrong
while i >= 0 or j >= 0:
    ...
return "".join(reversed(result))
✓ Right
while i >= 0 or j >= 0 or carry:
    ...

When the top column carries, the answer is one digit longer than both inputs. Without or carry in the condition, "1" + "1" returns "0" instead of "10".

Prepending to a string in the loop

✗ Wrong
result = str(total % 2) + result
✓ Right
result.append(str(total % 2))
# reverse once at the end

Strings are immutable, so each prepend copies the entire accumulated result, making the loop O(n²). Appending to a list and reversing once stays linear.

06

Edge cases

Both inputs are "0"

One column, no carry, and the result is "0" rather than an empty string.

Unequal lengths, e.g. "1" + "1111"

The missing digits read as 0, so no padding step is needed.

Carry out of the top column, "1" + "1"

The leftover carry is appended, giving "10".

Carry propagating the whole way, "1111" + "1"

Each column carries into the next, producing "10000".

Very long inputs near 10⁴ digits

Digit-wise addition is unaffected; an integer conversion would overflow in C++ and Java.

07

Complexity

Time
O(max(m, n))
Space
O(max(m, n))
One pass over the longer string. The output itself is the only significant storage.