[LeetCode]440. K-th Smallest in Lexicographical Order

Loading...

求字典序的第k个数

十叉树,比如10 ~ 20在这一层有10个数,如果20小于n,那么再找第三层100 ~ 200,每层step就min(n + 1, n2) - n1

根本在于以 cur 为根节点满足小于等于 n 的子节点个数有多少

public int findKthNumber(int n, int k) {
        //从根节点下面的第一个结点1开始遍历,由于数据范围很大,所以用long
        long cur = 1;
        //从1出发开始往后按字典序从小到大的顺序走k-1步到达的就是 字典序的第K小数字
        k -= 1;

        while (k > 0) {
            //得到以当前结点为根的所有子树节点数目
            int nodes = getNodes(n, cur);
            //如果k要大于当前根节点下所有子树结点的数目,就向右侧节点走(->2->3->4->5->6->7->8->9):字典序上升nodes位
            if (k >= nodes) {
                //减去已经遍历的个数
                k -= nodes;
                //根节点右移
                cur ++;
            } 
            //如果k小于当前根节点下所有子树结点的数目,说明答案就在当前根节点的子树结点中
            else {
                //减去根节点的数量1
                k -= 1;
                //将根结点移动到下一层(每一层右10个结点)
                cur *= 10;
            }
        }
        //最终k = 0时,就找到了答案
        return (int)cur;
    }

    // 计算以cur为根的子树节点数目,所有节点的值必须 <= n
    private int getNodes(int n, long cur){
        // 记录子树中的全部节点数目
        long totalNodes = 0; 
        // 当前节点右侧右边节点的值
        long next = cur + 1; 
        while(cur <= n){
            //取整行结点的个数,可能全部都满了,也可能是叶子结点,没有充满
            totalNodes += Math.min(n - cur + 1, next - cur);
            //cur - cur在当前层的第一个结点, next - cur右侧根结点的第一个结点
            next *= 10;
            cur *= 10;
        }
        return (int)totalNodes;
    }

作者:Meng_Xi
链接:https://leetcode-cn.com/problems/k-th-smallest-in-lexicographical-order/solution/tou-liao-liang-wei-da-lao-de-tu-he-ti-ji-fs9r/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值