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

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

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

1 2 9
10,11,12,13,14,15,16,17,18,19 20,21,22,23,24,25,26,27,28,29 90~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 # 去往下一层

猜你喜欢

转载自blog.csdn.net/weixin_43702920/article/details/107464281