题目链接
题目描述
给定整数 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。
解题思路
方法一:字典树(十叉树)


class Solution {public int findKthNumber(int n, int k) {// 当前字典树结点 (当前遍历到的数字)int cur = 1;// 到达第 k 个节点需要遍历 k-1 个结点// 当前 k 值表示剩余需要遍历的节点数k -= 1;while(k > 0){int nodes = getNodes(n, cur);// 如果当前子树的结点数小于等于 k, 则需要全部遍历if(nodes <= k){ // 向右侧节点走// 减去已经遍历过的子树k -= nodes;// 指向下一个新的结点++cur;}else{ // 向下往最左孩子节点走:字典序上升1位// 结果在当前子树中, 减去当前根节点--k;// 向下一层搜索cur *= 10;}}return (int)cur; // 最后cur停在的数字就是字典序的第K小数字}// 获取 cur 值下子树结点的个数private int getNodes(int n, long cur){long nodes = 0;long next = cur + 1;while(cur <= n){// 如果当前一层中有定值 n, 则只能取到n,末位从 0 开始nodes += Math.min(n - cur + 1, next - cur);// 计算下一层个数next *= 10;cur *= 10;}// 返回当前 cur 值下子树结点个数return (int)nodes;}}
- 时间复杂度 O(log n)
- 空间复杂度 O(1)
