LeetCode #165 Medium

Compare Version Numbers

Compare dotted version strings numerically per chunk: return −1, 0, or 1. "1.01" == "1.001", "1.0" == "1".

stringtwo-pointers
Open on LeetCode ↗
02

Intuition

Split on dots and compare chunk-by-chunk as integers — int() eats leading zeros for free. Different lengths? Missing chunks count as 0, so pad the shorter side conceptually.

How to spot this pattern

The trap is treating a version as a number or a string; it's neither — it's a sequence of integers compared left to right. Once you see it that way, the two remaining questions answer themselves: parse each part as an int (killing leading zeros), and treat missing trailing parts as 0 so 1.0 and 1 compare equal.

03

Approach

1

Chunks, not characters

"1.10" > "1.9" numerically though it's smaller lexicographically — so convert each chunk with int().

2

Walk to the longer length

Iterate max(len(a), len(b)) chunks, treating absent ones as 0 — that's how "1.0" equals "1".

3

First difference decides

Return on the first unequal pair; equal all the way → 0.

04

Solution & live demo

1class Solution:
2 def compareVersion(self, version1, version2):
3 a = [int(x) for x in version1.split(".")]
4 b = [int(x) for x in version2.split(".")]
5 for i in range(max(len(a), len(b))):
6 x = a[i] if i < len(a) else 0
7 y = b[i] if i < len(b) else 0
8 if x != y:
9 return 1 if x > y else -1
10 return 0
05

Common pitfalls

Comparing the strings directly

✗ Wrong
return (version1 > version2) - (version1 < version2)
✓ Right
a = [int(x) for x in version1.split(".")]

Lexicographic order puts "1.10" before "1.9" because '1' < '9', and "01" differs from "1". Parsing to integers is what makes 10 rank above 9 and leading zeros vanish.

Parsing as a float

✗ Wrong
if float(version1) > float(version2):
✓ Right
for i in range(max(len(a), len(b))):

A version can have more than one dot — float("1.2.3") raises, and even with one dot 1.10 becomes 1.1, ranking it below 1.9. Each component is independent, not a decimal fraction.

Stopping at the shorter version

✗ Wrong
for i in range(min(len(a), len(b))):
✓ Right
for i in range(max(len(a), len(b))):
    x = a[i] if i < len(a) else 0
    y = b[i] if i < len(b) else 0

1.0.1 versus 1 must report greater, but stopping at the shorter one compares only the leading 1 and calls them equal. Absent components are implicitly zero, which also makes 1.0 equal 1.

06

Edge cases

Leading zeros, "1.01" vs "1.001"

int() normalizes both to 1 → equal.

Trailing zero chunks, "1.0.0" vs "1"

Missing chunks read as 0 → equal.

07

Complexity

Time
O(n + m)
Space
O(n + m)
Split + one comparison pass.