Given an integer n
, return all the numbers in the range [1, n]
sorted in lexicographical order.
You must write an algorithm that runs in O(n)
time and uses O(1)
extra space.
Example 1:
Input: n = 13
Output: [1,10,11,12,13,2,3,4,5,6,7,8,9]
Example 2:
Input: n = 2
Output: [1,2]
Constraints:
1 <= n <= 5 * 10^4
A naive solution would involve generating all numbers from 1 to n
, converting them to strings, sorting the strings lexicographically, and then converting them back to integers. This approach is simple to understand but not efficient.
Code (Python):
def lexicalOrder_naive(n):
nums = list(range(1, n + 1))
nums_str = [str(num) for num in nums]
nums_str.sort()
result = [int(num_str) for num_str in nums_str]
return result
Time Complexity: O(n log n) due to the sorting step.
Space Complexity: O(n) to store the numbers and their string representations.
A more efficient approach is to use Depth-First Search (DFS) to generate the numbers in lexicographical order. We start with 1, then generate its children (10, 11, 12, ...), and so on, as long as the numbers are within the range [1, n].
Algorithm:
result
to store the numbers in lexicographical order.dfs(num, n, result)
:
num
to the result
list.next_num = num * 10 + i
.next_num
is within the range [1, n], call dfs(next_num, n, result)
.Code (Python):
def lexicalOrder(n):
result = []
def dfs(num, n, result):
if num > n:
return
result.append(num)
for i in range(10):
next_num = num * 10 + i
if next_num > 0 and next_num <= n:
dfs(next_num, n, result)
for i in range(1, min(10, n + 1)):
dfs(i, n, result)
return result
# Iterative version
def lexicalOrder_iterative(n):
result = []
curr = 1
for _ in range(n):
result.append(curr)
if curr * 10 <= n:
curr *= 10
else:
if curr >= n:
curr //= 10
curr += 1
while curr % 10 == 0:
curr //= 10
return result
Time Complexity: O(n). Each number is visited exactly once.
Space Complexity: O(1) excluding the output list. The recursive calls use stack space, but in the iterative version it is O(1).
Edge Cases:
n = 0
: The problem statement specifies 1 <= n <= 5 * 10^4
, so this case is invalid. However, returning []
would be a reasonable approach if it were allowed.n = 1
: The result should be [1]
.n = 9
: The result should be [1, 2, 3, 4, 5, 6, 7, 8, 9]
.n = 10
: The result should be [1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
.