leetcode440. 字典序的第K小数字

这题的整体思路是通过深度优先取寻找10叉树的层数,确定层数之后再广度查找答案的位置
比如对n= 303,k=206 先找到10叉树应该是四层的(根节点也算)范围(1-999)
对于1开头的一共有1+10+100个不满足,所以cur+1找2开头的,(95<111所以是2开头的)
又因为2开头的也有111个数,所以k应该是在2为前缀的子树里的
首先将2这个数减去看是否满足,206-111-1=94不满足,所以进入20为前缀的子树一共有1+10个
所以94-11 = 83 进入21,22,23,24,25,26,27,28. 28的时候分支下的个数11大于k=83-77=6
所以进入28分支成为了280并k减去了1(28这个数)k=5
进280,281,282,283都不满足并且k-4=1
到284时满足,k=0

def findKthNumber(n, k):
    def dfs(cur, n):  # 深度优先,确定层数并计算当前cur为根的节点的个数看是否在这一分支
        count = 0
        first = cur
        last = cur
        while first <= n:                      #first其实是层数比如n= 1221, first=10000时终止说明有4层
            count += min(last, n) - first + 1  #r如果这里的last>n说明不是满10叉树
            first *= 10                        #count计算当前前缀下的节点的个数
            last = last * 10 + 9
        return count

    k -= 1
    cur = 1
    while k:
        count = dfs(cur, n)
        if count <= k:               #如果小于k说明不在这个分支,换一个分支搜索
            k -= count
            cur += 1  # 广度优先
        else:                        #大于说明就在这个分支,进入分支搜索子节点
            k -= 1                   #进入分支时,当前节点要减掉
            cur *= 10
    return cur
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值