3.23每日一题
有点难,看了题解想到的
思想是看作一个树,先序遍历即为要求的字典序
class Solution {
public:
int getpointnum(int curr, int n){
//first和last保存这一个节点的每一层的头节点和尾节点
long first = curr;
long last = curr;
//pointnum保存搜索到了多少个节点
int pointnum = 0;
//结构应该是一个完全二叉树
//所以应该搜索到最后一层之后再往下搜索就会大于n
//因此以n作为搜索结束条件
while(first <= n){
//最后一层节点可能不满
//因此要用last和n的最小值作为这一层的最后一个节点
int tmp = last < n ? last : n;
//这一层的节点数
pointnum += tmp - first + 1;
//下一层节点的头尾
first *= 10;
last = last*10 + 9;
}
return pointnum;
}
int findKthNumber(int n, int k) {
//curr保存当前搜索到的节点
int curr = 1;
//已经找到了第1个数,所以k-1
k --;
while(k > 0){ //当k==0的时候表示已经找到第k个数
//getpointnum是查找当前节点下面一共有多少节点
//根据节点数判断k在不在这个节点的子树上
int pointnum = getpointnum(curr, n);
//如果节点数小于等于k,说明不在这个节点
//就跳到当前节点的兄弟节点,即curr+1
//并且上一个节点下面有pointnum个数
//所以也就跳过了pointnum个数,k-pointnum
if(pointnum <= k){
curr ++;
k -= pointnum;
}else{
//否则就在当前节点的子树上
//当前节点的第一个孩子是curr*10
//这时只跳过了一个节点,所以k-1
curr *= 10;
k --;
}
}
return curr;
}
};