leetcode_middle_44_386. Lexicographical Numbers

题意:

给一个数n,按照字典顺序返回1-n。


分析:

什么是字典顺序呢?观察例子,分析是按位比较,先比较最高位。

我们按照人脑思维,是应该怎么选出排序呢?首先1,10,11,12...19这样但是还有1124,111167,11111187,测试数据很大。如果遍历会很难判断,所以考虑直接按照字典顺序去生成。

我们的遍历搜索是什么路径和规律呢?

举例子:1 10 100 1000 1001 1002....如果位数没有达到最高,就一直乘10,然后往后遍历10个数。到1009 按照数值顺序再往后就是1010,但是不对101的字典顺序在1010之前。所以1009之后是101然后是1010....1019然后是1020,又不对,应该是102然后是1021...

以上是举例子,我们接着来理论分析,我们要保证 a = b+1 一般情况,就是在前面的位数相同的情况下最后一位a为空,b为0(比如100和1000),或者a为n,b为n+1(比如104和105)。所以我们肯定是从1,100,1000这么扩大位数,然后最后一位从0-9,也就是说我们假设最大是4位数,那么前三位100就是最小的第四位从空到0到9完了以后我们第三位变成101,第四位又从空到0到9.

所以理论总结规律就是:一个数(比如1000)按照最低位开始处理,从0到9,然后次低位加1,最低位继续从空到0到9.

所以显然这是一个10叉树的先序遍历回溯搜索。

                                                  1                   2                        3                    4                        5                   ......                   9          

         10        11     12     .......  19

100 101....

这很好理解由于  空<0<1<2<...<8<9

所以我们要在高位确定的情况下比较低位,然后再改变次低位。。。。。

public class Solution {
    List<Integer> list;
    int n;
    public List<Integer> lexicalOrder(int n) {
        list = new ArrayList<>();
        this.n = n;
        for(int i=1; i<=9; i++)   //因为没有根节点
            helper(i);
        return list;
    }
    
    private void helper(int i){
        if(i > n)
            return;
        list.add(i);              //来到当前结点,先放入(先序遍历)
        for(int j=0; j<=9 ;j++){  //遍历下层结点
            helper(i*10 + j);     //回溯到当前层  
        }                         
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值