题目描述
给定整数 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