今天刷到leetcode 440,发现有关字典序的一个方法:树。
问题如下:
给定整数 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 2 .....
| \ \ |
10 11 12... 20...
所以,从第一个树开始遍历,统计当前节点下面的子节点个数,如果大于k,则第k个肯定在这棵子树下面。那么移动当前节点到子节点(前序遍历)
如果子节点数小于k,证明在下一个子树下面。下一个子树就是cur+1。
移动到下一个节点时候,k要相应调整,应为已经遍历了相应的字典序。
class Solution {
public:
int findKthNumber(int n, int k) {
int cur = 1;
k--;
while(k > 0){
long cur_tree = cur, next_tree = cur+1;
int kids = 0;
while(cur_tree <= n){
kids += ((n + 1 < next_tree) ? n + 1 : next_tree) - cur_tree;
cur_tree *= 10;
next_tree *= 10;
}
if(kids <= k){
cur++;
k -= kids;
} else {
cur *=10;
k--;
}
}
return cur;
}
};