1 问题
数字以 0123456789101112131415… 的格式作为一个字符序列,在这个序列中第 2 位(从下标 0 开始计算)是 2 ,第 10 位是 1 ,第 13 位是 1 ,以此类题,请你输出第 n 位对应的数字。
数据范围: 0≤n≤10 ^ 9
示例1
输入:0
返回值:0
示例2
输入:2
返回值:2
示例3
输入:10
返回值:1
示例4
输入:13
返回值:1
2 答案
自己写的,暴力法,超出时间限制
class Solution:
def findNthDigit(self , n: int) -> int:
s = ''
i = 0
while len(s) <= 10 ** 9:
s += str(i)
i += 1
return int(s[n])
官方解
- 位数减法
我们尝试来找一下规律:
小于10的数字一位数,1~9,共9个数字,9位;
小于100的数字两位数,10~99,共90个数字,180位;
小于1000的数字三位数,100~999,共900个数字,2700位;
……
我们可以用这样的方式,不断减去减去前面位数较少的数字的那些位,锁定第n位所在的区间,即第n位是几位数。这个区间的起点值加上剩余部分除以这个区间的位数就可以定位n在哪个数字上,再通过n对位数取模可以定位是哪一位。(下标从0开始,还没有减去第一个数据0,start从1开始的,需要对n减1)
具体做法:
- step 1:通过对每个区间起点数字的计算,按照上述规律求得该区间的位数,n不断减去它前面区间的位数,定位到属于它的区间。
- step 2:通过除以位数定位n在哪个数字上,用字符串形式表示。
- step 3:通过在字符串上位置对几位数取模定位目标数字。
class Solution:
def findNthDigit(self , n: int) -> int:
digit = 1
start = 1
sum = 9
while n > sum:
n -= sum
start *= 10
digit += 1
sum = 9 * start * digit
num = start + (n - 1) // digit
index = (n - 1) % digit
return int(str(num)[index])
- 添0补齐法
上述思路是不断减去前面部分的,我们还可以考虑给数字增加前置0,让数字都变成相同的位数。比如我们要求第15个数字,可以在一位数前增加0,使其变成00 01 02 03 04 05 06 07 08 09,这样我们要求的数字都是两位数,相当于增加了10个位,也就要求这种情况下的第25个数字,这种情况下每个数是两位数,第25个数字属于25/2=12的一部分,那究竟是1还是2呢我们可以就看25对两位数取模,结果是第1位(下标从0开始),因此第25个数字就是2,也即是原来的第15位数字是2.
- step 1:使用循环求n是属于几位数,i从1位数开始,每次给它增加 10 ^ i 个0,即n位数往后推 10 ^ i
- step 2:找到目标数字后,通过数字对位数求除法找到该数字,转化为字符串类型。
- step 3:再通过对位数取模判断是哪一位数。
class Solution:
def findNthDigit(self, n: int) -> int:
i = 1
while i * pow(10, i) < n:
n += pow(10, i) # n 的位向后推
i += 1
return int(str(n // i)[n % i])
https://www.nowcoder.com/share/jump/9318638301699282190521