Leetcode 440 K-th Smallest in Lexicographical Order n叉树快速按层遍历

120 篇文章 1 订阅

Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n.

Note: 1 ≤ k ≤ n ≤ 109.

Example:

Input:
n: 13   k: 2

Output:
10

Explanation:
The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so the second smallest number is 10.

 

Accepted

10,496

Submissions

37,795

 

这个问题注意几点:

1. 刚好遍历是颗按照深度优先遍历阉割的n叉树

2. 假设这一层节点全满,这一层有效节点的个数是next-pre;如果不满,只能去找兄弟节点

3. 因此,按层遍历树可以很方便地求以某个pre为前缀的有效个数step

4. 如果这个step<=k,说明以res为前缀的子树没有累积到,去res的兄弟节点找,否则去res的孩子找

最后上代码:

class Solution:
    def findKthNumber(self, n, k):
        k -= 1
        res = 1
        while k > 0:
            step, pre, next = 0, res, res+1
            # 实际上按层遍历
            while pre <= n:
                # 以res为前缀的子树每层前缀pre<=n,共有节点数step<=n: 
                # 如果step<=k,说明到这颗子树为止还累计不到k,去下一个兄弟节点找
                # 否则说明结果以这个前缀开头
                step += min(n + 1, next) - pre
                pre *= 10
                next *= 10
            if step <= k:
                res += 1
                k -= step
            else:
                res *= 10
                k -= 1
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值