Find the Closest Palindrome looks like a search problem but is really a case analysis. The closest palindrome is never far away — it always comes from nudging the first half of the number, so we only ever build a handful of candidates and compare.
Problem. Given a number as a string n, return the palindrome closest in value to n that is
not equal to n. If two palindromes are equally close, return the smaller one.
Example: n = "1283" → answer "1331" (because |1283 − 1331| = 48, smaller than any other palindrome distance).
The slow way first
The brute force is to walk outward from n — check n+1, n-1, n+2, n-2, … and stop at the first palindrome. That is correct but can be hopeless: for a number like 10000000000000000 the nearest palindrome can be billions of steps away. We need to jump straight to the candidates instead of crawling.
The question to ask: what actually controls a palindrome? Only its first half. The back half is forced to mirror the front. So changing the answer means changing the prefix — and the closest palindromes come from the smallest possible prefix changes.
The idea: mirror the prefix, then nudge
Take the first half of n (the prefix) and mirror it to build a palindrome. The closest palindrome is one of just five candidates:
mirror(prefix)— same prefix, mirrored.mirror(prefix + 1)— the next palindrome up.mirror(prefix - 1)— the next palindrome down.99…9with one fewer digit — handles cases like1000 → 999.10…01with one more digit — handles cases like99 → 101.
The key insight: drop n itself from the set (we need a different palindrome), then pick the candidate with the smallest distance, breaking ties toward the smaller value.
Walk through it
Step through the animation. We split 1283 into the prefix 12, mirror it to 1221, then build 1331 (prefix + 1) and 1111 (prefix − 1). We also add the boundary palindromes 99 and 10001. Scoring every distance, 1331 is only 48 away and wins.
Pseudocode
prefix = first half of n (round up the middle digit)
candidates = {}
add mirror(prefix) # same prefix
add mirror(prefix + 1) # one palindrome up
add mirror(prefix - 1) # one palindrome down
add 99..9 with one fewer digit # length shrinks
add 10..01 with one more digit # length grows
remove n itself from candidates
return the candidate with smallest |candidate - n|, ties -> smaller valueThe Python solution
def closest_palindrome(n: str) -> str:
length = len(n)
prefix = int(n[: (length + 1) // 2])
def mirror(p):
s = str(p)
return int(s + s[length % 2:][::-1])
cands = {mirror(prefix)}
cands.add(mirror(prefix + 1))
cands.add(mirror(prefix - 1))
cands.add(10 ** (length - 1) - 1)
cands.add(10 ** length + 1)
cands.discard(int(n))
best = min(cands, key=lambda c: (abs(c - int(n)), c))
return str(best)prefixis the first half ofn, taking the middle digit when the length is odd ((length + 1) // 2).mirror(p)reflects the prefix;s[length % 2:]skips the middle digit on odd lengths so it is not duplicated.- We collect the three prefix-based palindromes plus the two length-boundary palindromes (
99…9and10…01). cands.discard(int(n))removesnitself — the answer must be a different palindrome.- The
minkey(abs(c - int(n)), c)picks the closest candidate and, on a tie, the smaller value.
Complexity
| Case | Time | Notes |
|---|---|---|
| Brute force (walk outward) | O(distance × len) (moderate) | can be astronomically far |
| Candidate set (this solution) | O(len) (moderate) | a constant 5 candidates to build |
O(len) (moderate)We never search the number line — we construct the only candidates that can win. Building each is linear in the digit count, and there are a fixed five of them.
When this pattern shows up
When "find the nearest valid X" has a brute force that could wander arbitrarily far, ask what structure constrains the answer. If a small, fixed set of constructions covers every case, enumerate those and pick the best — far faster than scanning.
Do not forget the two length-change candidates. Numbers like 1000 (closest is 999, one digit
shorter) and 99 (closest is 101, one digit longer) are only caught by the 99…9 and 10…01
boundaries — the prefix-mirror candidates miss them.
Practice
For n = 1283 with prefix 12, what three palindromes do mirror(12), mirror(13), and mirror(11) produce?
1. Why is walking outward from n (n+1, n-1, n+2, ...) a bad approach?
2. Which part of a number actually determines a palindrome?
3. Why do we add the 99..9 and 10..01 candidates?
4. When two palindromes are equally close to n, which do we return?