[
dp
dfs
]
BinarySearch 0566 Equation Typo
Problem statement
https://binarysearch.com/problems/Equation-Typo/
Solution
Quite difficult problem, I thought to solve it with bruteforce, where we add no more than 3
digits to each number, but in python (and possibly in other languages) it will give TLE. Let us use dp(i, j, k, carry)
, where it is the answer how many digits we need to add to make equation A[:i+1] + B[:j+1] + carry == C[:k+1]
possible.
The problem is what to do with extra zeroes, imagine the case 3 + 4862 = 26
, then we need to go to the negative index -2
to make it 403 + 4862 = 5265
.
- If
i <= -1 and j <= -1
means that digits inA
andB
are finished, so we need to add digits to numberC
. If balance is0
or-1
(it can not be smaller): in fact there can be cases:- When
prefix3 = 0, carry = 0
, then add nothing, in fact it will be coveredi <= -1
,j <= -1
andk <= -1
. - When
prefix3 = 1, carry = 1
, then add nothing. - When
prefix3 = 0, carry = 1
, then in factk <= -1
, so it will be covered later. - Also if we have
i == -1
orj == -1
, than one number is finished, another is not.
- When
-
If
k <= -1
, then it means that numberC
is finished, so we just need to add digits to eitherA
orB
. - If we already have equalty for given place, than we add it to options.
- Also we can try to add digit to number
A
: here we need to deal with case of extra zeroes. - Similar logic for number
B
. - Final case is to add digit to number
C
.
Complexity
It is O(n^3)
, where n
is maximum length of A, B, C
.
Code
### Code by Awice
class Solution:
def solve(self, s):
A, rest = s.split("+")
B, C = rest.split("=")
def process(A, i):
return (int(A[i]), int(A[:i+1])) if i >= 0 else (0, 0)
@lru_cache(None)
def dp(i, j, k, carry):
if i <= -1 and j <= -1 and k <= -1: return int(carry != 0)
last1, prefix1 = process(A, i)
last2, prefix2 = process(B, j)
last3, prefix3 = process(C, k)
# Nothing LHS
if i <= -1 and j <= -1:
rhs = prefix3 - carry
if -1 <= rhs <= 0:
return -rhs
if i == -1 or j == -1:
return len(str(rhs))
# Nothing RHS
if k <= -1:
return len(str(prefix1 + prefix2 + carry))
ans = float("inf")
# Don't add anything
carry2, lhs = divmod(carry + last1 + last2, 10)
if lhs == last3:
ans = dp(i - 1, j - 1, k - 1, carry2)
# Add to end of A
req = last3 - carry - last2
extra_zeros = max(0, -1 - i)
carry2 = 1 if req < 0 else 0
ans = min(ans, 1 + extra_zeros + dp(max(-1, i), j - 1, k - 1, carry2))
# Add to end of B
req = last3 - carry - last1
extra_zeros = max(0, -1 - j)
carry2 = 1 if req < 0 else 0
ans = min(ans, 1 + extra_zeros + dp(i - 1, max(-1, j), k - 1, carry2))
# Add to end of C
carry2, lhs = divmod(last1 + last2 + carry, 10)
ans = min(ans, 1 + dp(i - 1, j - 1, k, carry2))
return ans
return dp(len(A) - 1, len(B) - 1, len(C) - 1, 0)