[LeetCode] K-th Smallest in Lexicographical Order 字典顺序的第K小数字

简介:

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.

这道题是之前那道Lexicographical Numbers的延伸,之前让按字典顺序打印数组,而这道题让我们快速定位某一个位置,那么我们就不能像之前那道题一样,一个一个的遍历,这样无法通过OJ,这也是这道题被定为Hard的原因。那么我们得找出能够快速定位的方法,我们如果仔细观察字典顺序的数组,我们可以发现,其实这是个十叉树Denary Tree,就是每个节点的子节点可以有十个,比如数字1的子节点就是10到19,数字10的子节点可以是100到109,但是由于n大小的限制,构成的并不是一个满十叉树。我们分析题目中给的例子可以知道,数字1的子节点有4个(10,11,12,13),而后面的数字2到9都没有子节点,那么这道题实际上就变成了一个先序遍历十叉树的问题,那么难点就变成了如何计算出每个节点的子节点的个数,我们不停的用k减去子节点的个数,当k减到0的时候,当前位置的数字即为所求。现在我们来看如何求子节点个数,比如数字1和数字2,我们要求按字典遍历顺序从1到2需要经过多少个数字,首先把1本身这一个数字加到step中,然后我们把范围扩大十倍,范围变成10到20之前,但是由于我们要考虑n的大小,由于n为13,所以只有4个子节点,这样我们就知道从数字1遍历到数字2需要经过5个数字,然后我们看step是否小于等于k,如果是,我们cur自增1,k减去step;如果不是,说明要求的数字在子节点中,我们此时cur乘以10,k自减1,以此类推,直到k为0推出循环,此时cur即为所求:

class Solution {
public:
    int findKthNumber(int n, int k) {
        int cur = 1;
        --k;
        while (k > 0) {
            long long step = 0, first = cur, last = cur + 1;
            while (first <= n) {
                step += min((long long)n + 1, last) - first;
                first *= 10;
                last *= 10;
            }
            if (step <= k) {
                ++cur;
                k -= step;
            } else {
                cur *= 10;
                --k; 
            }
        }
        return cur;
    }
};

本文转自博客园Grandyang的博客,原文链接:字典顺序的第K小数字[LeetCode] K-th Smallest in Lexicographical Order ,如需转载请自行联系原博主。

相关文章
LeetCode 429. N-ary Tree Level Order Traversal
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
91 0
LeetCode 429. N-ary Tree Level Order Traversal
|
算法 Python
LeetCode 386. Lexicographical Numbers
给定一个整数 n, 返回从 1 到 n 的字典顺序。
91 0
LeetCode 386. Lexicographical Numbers
|
存储
LeetCode 107. Binary Tree Level Order Traversal II
给定二叉树,返回其节点值的自下而上级别顺序遍历。 (即,从左到右,逐下而上)。
84 0
LeetCode 107. Binary Tree Level Order Traversal II
|
Python
LeetCode 103. BTree Zigzag Level Order Traversal
给定二叉树,返回其节点值的Z字形级别遍历。 (即,从左到右,然后从右到左进行下一级别并在之间交替)。
79 0
LeetCode 103. BTree Zigzag Level Order Traversal
|
存储
LeetCode 102. 二叉树的层序遍历 Binary Tree Level Order Traversal
LeetCode 102. 二叉树的层序遍历 Binary Tree Level Order Traversal
LeetCode contest 183 5376. 非递增顺序的最小子序列 Minimum Subsequence in Non-Increasing Order
LeetCode contest 183 5376. 非递增顺序的最小子序列 Minimum Subsequence in Non-Increasing Order