逐步求解:
eg:n=548
对于012345678910111213.....先求出第548位对应的数所在“计数”:219;
求出第548位数字,对应“计数”的位数:219对应3位,d=3;
求出第548位数字,对应“计数”所在段的数字量:100-999共有900个,count=900;
求出219是从谁开始数的:100;
求出第548位数字,对应是219的第几位,对应第1位(从第0位开始);
去掉219第1位之后的数:21 (219从左到右,依次为第0 1 2位):
取出21的个位:21%10=1 即可
c++
class Solution {
public:
int findNthDigit(int n) {
if(n<10){
return n;
}
// d位的数字有count个
long d = 1;
long count = 9;
/*
第n位数字对应计数,有几位(d),计数区间(100-999)(3位数区间)总个数900(count)
第一区间 1-9, 数字个数9,数位个数9(1x9)(每个数1位,有9个数)
第二区间 10-99, 数字个数90,数位个数180(2x90)(每个数2位,有90个数)
第三区间 100-999, 数字个数900,数位个数2700(3x900)(每个数3位,有900个数)
*/
// 判断在第几区间,更新所在区间位数d,区间内数字个数count,数位个数n
while(n > d*count){// 数位个数=每个数几位*区间内数字个数,n>d*count不在此区间
n -= d*count; // 减去上个区间个数
d++; // 更新d
count *= 10; // 更新count
}// 跳出时n是所在区间内,从区间开始数字开始的第n位
// 找到第n位对应数字
int ds = pow(10,d-1); // 区间开始的数字(1,10,100,1000)
int dnum = ds + (n - 1)/d; // 此时n是该数字在该区间的第几位,整除该区间位数,得到该数字对应"计数"在区间的第几个计数,+区间开始数字,得到原始第n位对应计数
int dth = (n - 1) % d; // 该数字在该计数上的位置(从左到右)(每个"计数"有d位,求余)
return dnum / (int)(pow(10,d - dth - 1)) % 10;
// dnum / (10 ** (d - dth - 1)) 删去该该计数中该数字后的数字 eg219找1->先变为21
// 再求个位:21->1: %10
}
};
python
class Solution:
def findNthDigit(self, n: int) -> int:
if n < 10:
return n
d, count = 1, 9 # d位的数字有count个
# 先找到n是几位数第几个, 循环结束后 n是d位数的第 (n - 1) // d 个数
while n > d * count:
n -= d * count
d += 1
count *= 10
#print(d, count)
ds = 10 ** (d - 1) # d位数的开始的数
# 再确定n具体对应着哪个数
dnum = ds + (n - 1) // d
# 再确定n在dnum的第几位上
dth = (n - 1) % d
# d位数中的dnum的第dth位即为所求
#print(ds, dnum, dth)
return dnum // 10 ** (d - dth - 1) % 10