LeetCode刷题日记2022-3-23/440. 字典序的第K小数字-字典树

440. 字典序的第K小数字

题目描述

给定整数 n 和 k,返回 [1, n] 中字典序第 k 小的数字。

示例 1:

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

示例 2:

输入: n = 1, k = 1
输出: 1

提示:

  • 1 <= k <= n <= 109

题解思路

所谓字典序 就是先比较第一位的大小 然后再按第二位大小 第三位大小依次排序

在这里插入图片描述
最终排序的结果就如同上述的这个字典树

以 1 为根节点  
以 2 为根节点
以 3 为根节点
....
以 9 为根节点

我们要找到字典序第k小的字典序

首先

我们要分析

以 1 为根节点  
以 2 为根节点
以 3 为根节点
....
以 9 为根节点

的根节点有多少个节点 也就是有多少个数字

我们以 以 1 为根节点的字典树进行分析

1

10-19

100-109   110-119 120-129....... 190-199

也就是每个节点包含十个数

每层也就是有1 10 100 1000 ....... 个数字

我们遍历 以1 为根节点的字典树

  • 因此 我们要做的就是确定n是在以哪个节点为根的字典树
  • 沿着这棵树一直找到n所在的那一层 然后我们就可以找到n

题解代码

class Solution:
    def findKthNumber(self, n: int, k: int) -> int:
        def dfs(l,r):
        	# 如果当前层数最左边的数大于n则说明 我们越界了 返回上一层寻找 
            return 0 if l>n else min(r,n)-l+1+dfs(l*10,r*10+9)
        
        cur=1
        k-=1

        while k:
        	#查找以cur为节点的树有多少个子节点
            cnt=dfs(cur,cur)
            #判断节点数是否比k多
            #如果少于k则说明我们要找的k不在该节点下,我们将这个节点的数量减去,然后跳到下一个节点继续寻找
            #否则我们进入该节点的下一层寻找是否k是否位于该层
            if cnt<=k:
                k-=cnt
                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、付费专栏及课程。

余额充值