The Indian Engineer

Problem 386 Lexicographical Numbers

Posted on 5 mins

Depth-First Search Trie

Problem Statement

Link - Problem 386

Question

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:

Solution

class Solution {
public:
struct Node{
    Node* links[10];
    bool flag=false;
    bool containsKey(char ch){
        return links[ch-'0']!=NULL;
    }
    void put(char ch, Node* node){
        links[ch-'0'] = node;
    }
    Node* get(char ch){
        return links[ch-'0'];
    }
    void setEnd(){
        flag = true;
    }
    bool getEnd(){
        return flag;
    }
};
class Trie{
public:
    Node* root;

    Trie(){
        root = new Node();
    }
    void insert(string& num){
        Node* temp = root;
        for(int i=0; i<num.size(); i++){
            if(!temp->containsKey(num[i])){
                temp->put(num[i], new Node());
            }
            temp = temp->get(num[i]);
        }
        temp->setEnd();
    }
};

    void dfs(Node* root, int curr, vector<int>& ans){
        if(root==NULL){
            return;
        }
        if(root->getEnd()==true){
            ans.push_back(curr);
        }
        for(char ch='0'; ch<='9'; ch++){
            if(root->containsKey(ch)){
                dfs(root->get(ch), (curr*10)+(ch-'0'), ans);
            }
        }
    }

    vector<int> lexicalOrder(int n) {
        std::ios::sync_with_stdio(false);
        Trie trie;
        for(int i=1; i<=n; i++){
            string s = to_string(i);
            trie.insert(s);
        }

        vector<int> ans;
        dfs(trie.root,0,ans);
        return ans;
    }
};

Complexity Analysis

| Algorithm                    | Time Complexity | Space Complexity |
| ---------------------------- | --------------- | ---------------- |
| Trie with Depth-first Search | O(n log n)      | O(n log n)       |

Explanation

Intial Thoughts

To start, we should consider how numbers are sorted in lexicographical order. We can think of it like arranging words in a dictionary, where each digit position acts like a letter. We also need to find an approach that allows us to generate these numbers in the given time and space complexity. We should list the key constraints and try to find patterns or relationships between the numbers. Breaking down the problem into smaller parts, like understanding how to generate the numbers and how to ensure lexicographical order, can be helpful.

Intuitive Analysis

When solving this problem intuitively, we can start by thinking about how we would arrange these numbers manually. We can consider what would happen if we started with the smallest number and thought about how to generate the next one in lexicographical order. Using a tree or a similar data structure might be helpful in visualizing this process and generating all the possible numbers. Additionally, thinking about how to use the given constraints to limit the search space and ensure efficiency can help us to develop an effective solution strategy. Considering the use of a Trie data structure to organize the numbers and a depth-first search to find all the numbers in lexicographical order could also be a good approach.

1. Intuition

2. Implementation


Complexity Analysis

Time Complexity:

Space Complexity:


Footnote

This question is rated as Medium difficulty.