3.23每日一题440字典序的第k小数字

3.23每日一题

在这里插入图片描述有点难,看了题解想到的
思想是看作一个树,先序遍历即为要求的字典序
在这里插入图片描述

class Solution {
public:
    int getpointnum(int curr, int n){
    	//first和last保存这一个节点的每一层的头节点和尾节点
        long first = curr;
        long last = curr;
        //pointnum保存搜索到了多少个节点
        int pointnum = 0;
        //结构应该是一个完全二叉树
        //所以应该搜索到最后一层之后再往下搜索就会大于n
        //因此以n作为搜索结束条件
        while(first <= n){
        	//最后一层节点可能不满
        	//因此要用last和n的最小值作为这一层的最后一个节点
            int tmp = last < n ? last : n;
            //这一层的节点数
            pointnum += tmp - first + 1;
            //下一层节点的头尾
            first *= 10;
            last = last*10 + 9;
        }
        return pointnum;
    }
    int findKthNumber(int n, int k) {
    	//curr保存当前搜索到的节点
        int curr = 1;			
        //已经找到了第1个数,所以k-1
        k --;	
        while(k > 0){	//当k==0的时候表示已经找到第k个数
        	//getpointnum是查找当前节点下面一共有多少节点
        	//根据节点数判断k在不在这个节点的子树上
            int pointnum = getpointnum(curr, n);
            //如果节点数小于等于k,说明不在这个节点
            //就跳到当前节点的兄弟节点,即curr+1
            //并且上一个节点下面有pointnum个数
            //所以也就跳过了pointnum个数,k-pointnum
            if(pointnum <= k){
                curr ++;
                k -= pointnum;
            }else{
            //否则就在当前节点的子树上
            //当前节点的第一个孩子是curr*10
            //这时只跳过了一个节点,所以k-1
                curr *= 10;
                k --;
            }
        }
        return curr;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值