之前的做法过于复杂了LeetCode 440. 字典序的第K小数字_Sasakihaise_的博客-CSDN博客
以至于现在看到这道题完全忘记怎么写了,于是今天看了看官方题解,重新整理一下思路
【分析】我们用一个getCnt(pre, limit)来计算以pre开头,不超过limit的数的个数,初始时肯定以1开头,对于以1开头的数字可能有:
1 : 1-1 + 1 = 1个
10-19: 19 - 10 + 1 = 10个
100-199: 199 - 100 + 1 = 100个
1000-1999: 1999 - 1000 + 1 = 1000个
我们可以发现上界是*10,而下界则是*10+9,总的个数就是下界-上届+1,但是下界需要和limit进行比较
这样就可以得到以pre开头的数字个数n了,用这个n和k进行比较:
如果n < k,说明第k个不是以pre开头的,将pre+1,同时将k-n
如果n>=k,说明第k个就是以pre开头,然后需要再细化以pre开头的,去寻找以pre*10开头的个数,同时k-=1(-掉pre本身),直到k==1返回pre即可
class Solution {
// 7:00. 29
public long getCnt(int pre, int limit){
long first = pre, last = pre;
long ret = 0;
while(first <= limit){
ret += Math.min(last, limit) - first + 1;
first *= 10;
last = last * 10 + 9;
}
return ret;
}
public int findKthNumber(int n, int k) {
int pre = 1;
while(k > 1){
long cnt = getCnt(pre, n);
if(cnt < k){
k -= cnt;
pre += 1;
}else{
k -= 1;
pre *= 10;
}
}
return pre;
}
}