leetcode刷题:440. 字典序的第K小数字

在这里插入图片描述
假设要找到第12小的字典序数(101)

解题要点:
(1) 数字为i的前缀一定比数字为i+1的前缀小,位置靠前。

129
10,11,12,13,14,15,16,17,18,1920,21,22,23,24,25,26,27,28,2990~99
101,102,103

(2) 如何求得前缀为i的树有多少个结点?
针对每一层,下一个前缀减去当前前缀

  1. k位置的数在i 这个前缀树里时候 n+1 - prefix
  2. k位置的数不在这个i(例如,10)的前缀树里,那么查看最邻近的前缀树,比如i+1(11)
    总结 从i前缀跨越到下一个前缀即i+1,需要min(next_prefix, n+1) - prefix
class Solution:
    def findKthNumber(self, n: int, k: int) -> int:
        # 同一层的两个节点间,移动需要的步数
        def count_steps(prefix, next_prefix) -> int:
            # 逐层累加步数
            cnt = 0
            while prefix <= n:
                cnt += min(next_prefix, n+1) - prefix # 本层中有多少个结点。
                prefix, next_prefix = prefix * 10, next_prefix * 10 # 去往下一层。
            return cnt


		#开始搜索,如图目标在当前前缀下,去往下一层
        cur_val, idx = 1, 1
        while True:
            if idx == k:
                return cur_val
            steps = count_steps(cur_val, cur_val + 1) # 这个前缀下有多少个点
            if idx + steps <= k:
                idx += steps #去往下一个后缀,同层node
                cur_val = cur_val + 1 # 去往同层下一个
            else:
                idx += 1 # 顺序枚举
                cur_val = cur_val * 10 # 去往下一层
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万物琴弦光锥之外

给个0.1,恭喜老板发财

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值