字典序 Leetcode题目

1. 440. 字典序的第K小数字

给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字。

注意:1 ≤ k ≤ n ≤ 109。

示例:

输入:
n: 13   k: 2

输出:
10

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

解法1:   

class Solution:
    def findKthNumber(self, n: int, k: int) -> int:
        # 字典序, 按 字典排序 1 10 100 ...2
        # 1 <= k <= n <= 10^9; 
        # [1, n] 第k小的数字, 所以 字典序中数 不能超过n;
        # prefix 和 n, [1, n]中第k个数(字典排序 也就是第k小的数)
        # 十叉树
        def cal_count(n, prefix, next_prefix):
            count = 0
            while prefix <= n:
                count += min(next_prefix, n+1) - prefix # 计算个数 所以+1
                prefix = prefix*10  # 下移一层
                next_prefix = next_prefix * 10
            return count
        prefix = 1  
        k = k - 1 # 第k小, 索引-1
        while k > 0:
            step = cal_count(n, prefix, prefix+1)  # 用来计算prefix移动到prefix+1需要移动多少步
            if step <= k: # 同层移动
                k = k - step
                prefix = prefix + 1  # 本层 右移一个
            else: # step > k; 往下层移动
                k = k - 1 # 下移 要移动一次
                prefix = prefix * 10
        return prefix  # prefix就是要找的值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值