440. K-th Smallest in Lexicographical Order

65 篇文章 0 订阅
23 篇文章 0 订阅

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 1

思路:其实就是在遍历trie树,要么往右走,要么往下走

然后考虑到数据量很大,不要遍历,而是求出子树有多少个值小于maxValue,然后再决定怎么走

子树有多个值有点trick,比如1-2,maxValue=13的情况下,1-2的子树有(1-2)+(10-13)

再比如1-2,maxValue=1300的情况下,1-2的子树有(1-2)+(10-20)+(100-200)+(1000-1300)


class Solution:
    def findKthNumber(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        def count(l,r,maxV):
            res = 0
            while l <= maxV:
                res += min(maxV+1,r) - l
                l *= 10
                r *= 10
            return res
        
        # k==1 is the answer
        res = 1
        while k > 1:
            cnt = count(res, res+1, n)
            if k >= cnt+1:
                k -= cnt
                res += 1
            else:
                k -= 1
                res *= 10
        return res
    
s=Solution()
print(s.findKthNumber(13, 2))
print(s.findKthNumber(10000, 10000))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值