1.暴力法
即枚举每一个数字,求出该数字是几位数,并把该数字的位数和前面所有数字的位数累加,如果位数之和仍然小于或者等于n,则继续枚举下一个数字。当累加的数位大于n时,第n位数字一定出现在这个数字里,从中找出对应的值
缺点:效率比较低
2.数学法
0-9 共10个数字,每个数字提供一位
10-99 共90个数字,每个数字提供2位
100-999 共900个数字,每个数字提供3位
1000-9999 共9000个数字,每个数字提供4位
......
利用如下规律,判断n在哪个区间
可以发现如果把最初的0取掉,每一轮增加的位数都是9*pow(10,k-1)*k,其中k表示当前是第几轮(或者说该轮中的数字的位数,如第一轮1位数,第二轮是2位数)
每判断一轮n的值就变为N-9*pow(10,k-1)*k,直到N小于0,
对于每一轮,都记录n减小之前的值,设为num,
对于最后的num,
设a=(num-1)/k
b=(num-1)%k
此处的1表示最初未计算的0
a=a+pow(10,k-1)
找到a的第b位即可
以1001为例:
初始1001>0 n=992>0 n=812>0
num=1001, num=992 num=812
n=1001-9=992 n=991-180=812 n=812-2700<0 循环结束
a=(812-1)/3=270 三位数的起始值是100,即pow(10,3-1);
b=(812-1)%3=1
a=270+100=370
a的第1位是7,即为最终的结果
代码如下:
class Solution {
public:
int findNthDigit(int n) {
int k=0,num=0;
if(n<10)
return n;
while(n>0)
{
num=n;
n=n-9*pow(10,k)*(k+1);
k++;
}
int a=(num-1)/k;
int b=(num-1)%k;
a=a+pow(10,k-1);
string s=to_string(a);
return int(s[b]-'0');
}
};