leetcode440字典序的第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。
解答:
用十叉树的结构模拟查找
计算每一个子树的节点个数,找节点在哪个子树里,使用k-子树节点个数,当k<=此子树节点数或k-1<此子树节点个数,说明k在此子树内
如果确定下来在哪个子树,再从子树的根向右和下,依次减1。

int findKthNumber(int n, int k) {
		int cur = 1;//目前子树根节点
		--k;
/*--k不是因为cur=1,我觉得是判断的第k-1个节点位置在哪个树里,在里边while下边的判断if(step<=k)此k是多减过一个1的,是判断第k-1个在此子树,所以第k个 是需要cur++是下一个子树的第一个,如果step>k就是他们都在这个子树里,向下走,考虑边界情况,如果是向下走的第一个是第k个,那k-1<step时就是进循环cur*=10,可以先向下看。
*/
		while (k > 0) {//这里不可等于0,如果等于0就直接返回就好,不需要再找子树
			long step = 0, first = cur, last = cur + 1;//first记录走到哪层第一个节点,step记录此子树节点数,last为此层下一个子树的第一个节点即first尾+1
			while (first <= n)//一直到此子树的尾,当first比原本层数高了之后出循环
			{
				step = min(last,(long) n + 1) - first;//记录此层节点数
				first *= 10;
				last *= 10;
			}
			//走到尾了,此时记录下了step的 值即子树的值
			//不在则向右走,换下一个子树,此k是多减过一个1的,是判断第k-1个在此子树,所以第k个 是需要cur++是下一个子树的第一个
			if (k >= step) {
				cur++;
				k -= step;
			}
			//在则向下走,k--是走了此根节点,向下走继续分哪个子树。
			else if (k < step) {
				k--;
				cur *= 10;
			}
		}
		return cur;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值