Solve the Equation: Parsing and Simplifying Linear Equations
Solve the Equation is LeetCode 640, rated Medium. Think back to algebra class: you have an equation with x on both sides, and you need to simplify. Collect x terms on one side, constants on the other, and divide. That is exactly what this problem asks you to do, except your "student" is a program that has to parse a string character by character. The challenge is not the math. It is the string parsing.
Why this problem matters
String parsing problems show up constantly in interviews and real-world code. Compilers, calculators, configuration parsers, and data importers all boil down to the same skill: scanning through characters, tracking state, and accumulating results. Solve the Equation is a clean, focused version of that pattern. It combines basic math with careful token extraction, and it tests whether you can handle signs, implicit coefficients, and edge cases without getting tangled up.
The approach
The idea is simple. Split the equation at the = sign (conceptually, not literally). Walk through the string character by character, and for each side, accumulate two things:
- x-coefficient total: the sum of all coefficients in front of
x - constant total: the sum of all standalone numbers
As you scan, you track the current sign (+1 or -1) and build up multi-digit numbers. When you see an x, the number you have been building (or 1 if there is no number) gets added to the coefficient total with the current sign. When you see +, -, or reach the end of a side, the number you have been building gets added to the constant total.
After processing both sides, you have left_coeff * x + left_const = right_coeff * x + right_const. Rearrange to (left_coeff - right_coeff) * x = right_const - left_const. If the combined coefficient is zero and the combined constant is also zero, there are infinite solutions. If the coefficient is zero but the constant is not, there is no solution. Otherwise, divide to get x.
The solution
def solve_equation(equation: str) -> str:
def parse(s: str):
coeff = 0
const = 0
num = 0
sign = 1
has_num = False
i = 0
while i < len(s):
ch = s[i]
if ch.isdigit():
num = num * 10 + int(ch)
has_num = True
elif ch == 'x':
coeff += sign * (num if has_num else 1)
num = 0
has_num = False
elif ch == '+' or ch == '-':
const += sign * num
num = 0
has_num = False
sign = 1 if ch == '+' else -1
i += 1
const += sign * num
return coeff, const
left, right = equation.split('=')
lc, ln = parse(left)
rc, rn = parse(right)
a = lc - rc
b = rn - ln
if a == 0 and b == 0:
return "Infinite solutions"
if a == 0:
return "No solution"
return f"x={b // a}"
The parse function does all the heavy lifting. It walks through a string (one side of the equation), tracking the current sign and accumulating digits. When it hits x, whatever number has been built becomes the coefficient. When it hits + or -, the current number becomes a constant. At the end of the string, we flush any remaining number.
The trickiest part is handling implicit coefficients. In expressions like x+2x-x, the first x has an implicit coefficient of 1, and -x has a coefficient of -1. The has_num flag distinguishes between "no digits seen yet" (use 1) and "the digit 0 was explicitly given" (use 0).
Step-by-step walkthrough
Let's trace through x+5-3+x=6+x-2 step by step. The answer should be x=2.
Step 1: Parse "x" (left side)
Step 2: Parse "+5" (left side)
Step 3: Parse "-3" (left side)
Step 4: Parse "+x" (left side)
Step 5: Hit "=" (switch to right side)
Step 6: Parse "6" (right side)
Step 7: Parse "+x" (right side)
Step 8: Parse "-2" (right side)
Step 9: Combine and solve
After parsing, we have left_coeff=2, left_const=2, right_coeff=1, right_const=4. That gives us (2-1)x = 4-2, so x = 2.
Complexity analysis
| Metric | Value | Why |
|---|---|---|
| Time | O(n) | Single pass through the equation string |
| Space | O(1) | Only a handful of integer variables |
The split('=') creates two substrings, but you could avoid that by scanning the original string and flipping sides when you hit =. Either way, the work is linear in the length of the input.
Edge cases to watch for
These come up in testing and interviews:
- Infinite solutions.
x=xor2x+3=x+3+x. After simplification, coefficient is 0 and constant is 0. Return"Infinite solutions". - No solution.
x=x+2. After simplification, coefficient is 0 but constant is nonzero. Return"No solution". - x=0.
x+1=1givesx=0. This is a valid answer, not a special case. Make sure you do not accidentally confuse "coefficient is zero" with "answer is zero". - Large coefficients.
0x=0has infinite solutions.2x=4givesx=2. Multi-digit coefficients like123xshould be handled by the digit accumulation loop. - No x on one side.
5=x+3is valid. The left side has coeff=0, const=5. The right has coeff=1, const=3. Result: x=2. - Negative results.
x+3=0givesx=-3. Make sure your integer division handles negative numbers correctly.
The building blocks
This problem is built on one core pattern: linear string parsing with state tracking.
You scan left to right, maintain a sign and a number accumulator, and dispatch based on what character you see. This same structure drives many other problems:
- Basic Calculator (LeetCode 224): same character-by-character parsing, but with parentheses that require a stack for save/restore
- Basic Calculator II (LeetCode 227): adds multiplication and division, requiring operator precedence handling
- Evaluate Reverse Polish Notation (LeetCode 150): processes tokens with a stack, but the core idea of "scan, accumulate, dispatch" is the same
Once you can write a clean parser for Solve the Equation, the jump to these harder problems is mostly about adding a stack or a precedence table. The scanning loop itself stays the same.
From understanding to recall
Solve the Equation looks simple on paper, but under interview pressure, the details pile up. How do you handle x with no coefficient? What about -x? Do you flush the number when you see x or when you see the next operator? These are not conceptual questions. They are recall questions.
Spaced repetition is the fix. You write the parsing loop from memory at increasing intervals. Each repetition reinforces the sign tracking, the has_num flag, and the flush-on-operator pattern. After a few rounds, the code flows without hesitation. You do not pause to think about whether -x needs special handling because you have already written it correctly a dozen times.
Related posts
- Basic Calculator - The same character-by-character parsing pattern, extended with a stack for handling parenthesized subexpressions
- Basic Calculator II - Adds operator precedence to the parsing loop, building on the same sign-tracking foundation
- Evaluate Reverse Polish Notation - A stack-based expression evaluator that uses the same scan-and-dispatch approach with a different notation
CodeBricks breaks the equation parser into its reusable building blocks and drills them with spaced repetition. You type the solution from scratch each time, so when LeetCode 640 or any string-parsing problem shows up in an interview, the code flows without hesitation.