例:n = 365, k = 299
算法步骤:先求出当前节点下的所有节点
- 从节点1开始,即cur = 1, next = 2;求出节点1下所有节点数count
- 每走过一颗子树,重新计算k。k <= 0 就找到答案
- 如果count <= k 则往右走;
- 如果count > k 则往下走。
- 代码
public int findKthNumber(int n, int k) {
// 之所以long定义,防止溢出
long cur = 1;
// 刚进来就要走1,所以k先减1
k--;
// k == 0就找到了
while (k > 0) {
// 获取当前节点下的总节点数(包括当前节点)
int count = countNodes(n, cur);
// 节点数不超过k,重新计算k,当前节点右移
if (count <= k) {
cur++;
k -= count;
} else { // 节点数超过k了,节点往下移动,k减去当前节点
cur *= 10;
k--;
}
}
return (int) cur;
}
/**
* 获取当前节点下的总节点数(包括当前节点)
* @param n
* @param cur
* @return
*/
public int countNodes(int n, long cur) {
// 当前节点的右节点
long next = cur + 1;
long ans = 0;
while (cur <= n) {
// n不在当前节点下:next - cur (next的左边全要了)
// n在当前节点下:n - cur + 1 (只要其中一部分)
ans += Math.min(next - cur, n - cur + 1);
// 往下走
cur *= 10;
next *= 10;
}
return (int) ans;
}