Problem Restatement
We are given two binary strings, a and b.
Each string contains only characters "0" and "1".
We need to return their sum as a binary string.
The official constraints are 1 <= a.length, b.length <= 10^4, both strings contain only binary digits, and neither string has leading zeroes except the string "0" itself.
Input and Output
| Item | Meaning |
|---|---|
| Input | Two binary strings a and b |
| Output | Their sum as a binary string |
| Characters | Only "0" and "1" |
| Leading zeroes | Not present except for "0" |
Function shape:
def addBinary(a: str, b: str) -> str:
...Examples
For:
a = "11"
b = "1""11" is binary for 3.
"1" is binary for 1.
Their sum is 4, which is:
"100"So the answer is:
"100"For:
a = "1010"
b = "1011"These represent:
1010 = 10
1011 = 11Their sum is 21, which is:
"10101"So the answer is:
"10101"First Thought: Convert to Integers
In Python, we could write:
return bin(int(a, 2) + int(b, 2))[2:]This is short and works in Python.
But the problem is meant to test manual binary addition. In many languages, the binary strings may be too long for normal integer types.
So we should add the strings directly.
Key Insight
Binary addition works like decimal addition, but each digit is base 2.
We add from right to left.
At each step, we add:
- The current bit from
a - The current bit from
b - The carry from the previous step
The result bit is:
total % 2The next carry is:
total // 2For example:
a bit | b bit | Carry in | Total | Result bit | Carry out |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 2 | 0 | 1 |
| 1 | 1 | 1 | 3 | 1 | 1 |
Algorithm
Use two pointers:
i = len(a) - 1
j = len(b) - 1Use a carry:
carry = 0Use a list to collect result bits in reverse order:
ans = []While there is still work to do:
while i >= 0 or j >= 0 or carry:- Start with
carry. - Add
a[i]ifiis valid. - Add
b[j]ifjis valid. - Append
total % 2. - Set
carry = total // 2. - Move both pointers left.
At the end, reverse the collected bits and join them.
Correctness
The algorithm processes bits from least significant to most significant, which is the standard order for addition with carry.
At each position, total is exactly the sum of the two input bits at that position plus the carry from all lower positions. The algorithm writes total % 2, which is the correct binary digit for the current position, and carries total // 2, which is the correct amount to add to the next higher position.
If one string is shorter, the algorithm treats missing bits as 0. This matches normal arithmetic.
The loop continues while either string has remaining bits or there is a carry. Therefore no input bit or final carry is lost.
Since the result bits are generated from right to left, reversing them produces the correct binary sum from most significant to least significant.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(max(m, n)) | We process each bit once |
| Space | O(max(m, n)) | The result can be one bit longer than the longer input |
Here, m = len(a) and n = len(b).
Implementation
class Solution:
def addBinary(self, a: str, b: str) -> str:
i = len(a) - 1
j = len(b) - 1
carry = 0
ans = []
while i >= 0 or j >= 0 or carry:
total = carry
if i >= 0:
total += ord(a[i]) - ord("0")
i -= 1
if j >= 0:
total += ord(b[j]) - ord("0")
j -= 1
ans.append(str(total % 2))
carry = total // 2
return "".join(reversed(ans))Code Explanation
Start from the rightmost bit of each string:
i = len(a) - 1
j = len(b) - 1Initialize the carry:
carry = 0Store answer bits in reverse order:
ans = []The loop continues while there are bits left or a carry remains:
while i >= 0 or j >= 0 or carry:Begin each column addition with the carry:
total = carryIf a still has a bit, add it:
if i >= 0:
total += ord(a[i]) - ord("0")
i -= 1If b still has a bit, add it:
if j >= 0:
total += ord(b[j]) - ord("0")
j -= 1The current binary result bit is:
total % 2The carry for the next position is:
total // 2Finally, reverse and join:
return "".join(reversed(ans))Testing
def run_tests():
s = Solution()
assert s.addBinary("11", "1") == "100"
assert s.addBinary("1010", "1011") == "10101"
assert s.addBinary("0", "0") == "0"
assert s.addBinary("1", "0") == "1"
assert s.addBinary("1111", "1") == "10000"
assert s.addBinary("101", "11") == "1000"
assert s.addBinary("100", "110010") == "110110"
print("all tests passed")
run_tests()| Test | Why |
|---|---|
"11" + "1" | Official example |
"1010" + "1011" | Official example with longer result |
"0" + "0" | Smallest values |
"1" + "0" | No carry |
"1111" + "1" | Carry through all bits |
"101" + "11" | Different lengths |
"100" + "110010" | Much different lengths |