440 字典序的第K小数字

题目描述:
给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字。
注意:1 ≤ k ≤ n ≤ 109。

示例 :
输入:
n: 13 k: 2
输出:
10
解释:
字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。

方法1:
主要思路:解题汇总链接
(1)按照多叉树进行遍历,其实也有点像字典树;
(2)先找出当前结点下能够满足小于 n 的数字的数量,若该数量大于k,说明需要在该结点继续深入下一层,若小于等于k,则说明可以找同一层的下一个相邻结点,同时调整k的值,直到k减小到0;

class Solution {
public:
    int findKthNumber(int n, int k) {
        int cur_v=1;//初始化
        --k;
        while(k>0){
            long long count=0,left=cur_v,right=cur_v+1;
            while(left<=n){//找出在给出的值的范围内的该节点下的所有值的数量
                count+=min(right,(long long)n+1)-left;
                left*=10;
                right*=10;
            }
            if(count<=k){//若当前该节点下的结点数量小于等于k,则需要遍历到同一层的相邻结点
                ++cur_v;//相邻结点的值
                k-=count;//减去当前结点下的所有结点数量
            }
            else{//遍历当期结点的下一层的结点
                cur_v*=10;
                --k;
            }
        }
        return cur_v;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值