Compare two version numbers version1 and version2. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. You may assume that the version strings are non-empty and contain only digits and the . character. The . character does not represent a decimal point and is used to separate number sequences.
Here is an example of version numbers ordering:
⏰ Time complexity: O(N) — we split both strings and parse each numeric token once; N is the total length of the input strings.
🧺 Space complexity: O(L) — splitting creates token arrays (L = total number of components across both versions).
Method 1b - Iterative using split and two-pointers based#
This variant also uses split, but advances a pointer over the token arrays and handles missing parts explicitly; useful when you prefer an explicit loop over for.
Same idea as 1a: compare numeric components left-to-right, treating missing parts as 0. Using pointers over split arrays emphasizes step-by-step token comparison and early exits.
Tokenizers stream the numeric components one by one and are convenient when you want to avoid creating full arrays of tokens; the algorithm remains a left-to-right numeric comparison.
classSolution:
defcompareVersion(self, version1: str, version2: str) -> int:
# iterate through tokens by index; splitting once for simplicity a = version1.split('.')
b = version2.split('.')
i =0while i < len(a) and i < len(b):
n1 = int(a[i])
n2 = int(b[i])
if n1 < n2:
return-1if n1 > n2:
return1 i +=1# check remaining tokens on either sidewhile i < len(a):
if int(a[i]) >0:
return1 i +=1while i < len(b):
if int(b[i]) >0:
return-1 i +=1return0
⏰ Time complexity: O(N) — processes each token once; N denotes total input length.
🧺 Space complexity: O(1) additional — uses iterators/single-pass checks and only constant extra storage (apart from the input tokens when using split, but no large auxiliary structures).