Problem Description
Given an integer n, return all the numbers in the range [1, n] sorted in lexicographical (dictionary) order. The algorithm should run in O(n) time and use O(1) extra space.
Key Insights
- The lexicographical order is similar to how words are sorted in a dictionary.
- A depth-first traversal approach can generate the sequence without using additional space for storing intermediate results (aside from the output list).
- The trick: Start from 1 and try to go as deep as possible by multiplying by 10; if that is not possible, try to increase the current number by 1.
- When reaching a dead-end (i.e., when the next number would exceed n or the last digit is 9), backtrack by dividing by 10 until you can increment safely.
Space and Time Complexity
Time Complexity: O(n) - Each number from 1 to n is generated exactly once. Space Complexity: O(1) - No extra space is used apart from the output list (ignoring recursion stack/constant pointers).
Solution
We use an iterative depth-first search (DFS) style approach:
- Start with the number 1.
- For each number appended in the result:
- If multiplying the current number by 10 does not cause the number to exceed n, move downward in the lexicographical tree by setting current = current * 10.
- Otherwise, if the current number is not at the end of a branch (i.e., its last digit isn’t 9) and adding 1 does not exceed n, simply increment current by 1.
- If neither move is possible, repeatedly backtrack by dividing the current number by 10 until we can increment until the next valid number.
- Continue until all numbers up to n are added.
This process mimics a DFS on a virtual tree where each node represents a number. The left-most branch (multiplying by 10) gives lexicographically smaller numbers, while the right siblings come from adding 1. The algorithm avoids extra space by directly computing the next value from the current number.