440-按字典序第k小的数

Description
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.

问题描述
给定整数n和k,找出[1, n]中按字典序排序的第k小的整数
注意,1 <= k <= n <= 109


问题分析

这题用到了十进制树,如果想弄清楚这个算法的话,可以看看这个链接
https://leetcode.com/problems/k-th-smallest-in-lexicographical-order/discuss/92242/ConciseEasy-to-understand-Java-5ms-solution-with-Explaination

算法的关键是计算相邻节点的距离并与k比较,若大于k说明,需将当前节点由十进制树下移(1的话变为10)并且将k - 1(因为按顺序的角度看,当前节点下移意味着只前进了一步),若小于等于k,则将当前节点在十进制树中右移并且减去相邻节点距离


解法

class Solution {
    public int findKthNumber(int n, int k) {
        int n1 = 1;

        k--;

        while(k > 0){
            int steps = calcSteps(n, n1, n1 + 1);
            //若距离大于k,则下移,在十进制树中就是乘以10,并且k-1,相当于前进一步
            //若距离小于等于k,则右移,当前节点加1,并且k - steps
            if(steps > k){
                k -= 1;
                n1 *= 10;
            }else{
                k -= steps;
                n1 += 1;
            }
        }

        return n1;
    }
    //相邻节点距离
    private int calcSteps(int n, long n1, long n2){
        int steps = 0;

        while(n1 <= n){
            steps += Math.min(n + 1, n2) - n1;
            n1 *= 10;
            n2 *= 10;
        }

        return steps;
    }
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LaputaFallen/article/details/79967059
个人分类: 算法与数据结构
所属专栏: leetcode全解
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭