面试题44.数字序列中某一位的数字
题目
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
解题思路
解法1:(超时O(n))
直接序列化到n再取字符串的第n个数O(n)
class Solution:
def findNthDigit(self, n: int) -> int:
#简单思路:直接序列化到n再取字符串的第n个数O(n)
strNums = "".join(map(str,range(n+1)))
print(strNums)
return int(strNums[n])
解法2:
寻找数字规律。
- 确定n所在数字的位数digit
- 确定n所在的数字num
- 确定n属于num的第几位res
我们跳过不需要的数字,从而缩小查找范围。比如求第840位(n=840)对应的数字num对应的位res,我们先得到:
- 0-9: 最大9位
- 10-99:最大90*2=180位
- 100-999:最大900*3=2700位
从而有从
1
0
d
i
g
i
t
1
0
d
i
g
i
t
−
1
10^{digit}~10^{digit-1}
10digit 10digit−1内的最大位数为
9
×
s
t
a
r
t
×
d
i
g
i
t
9\times start \times digit
9×start×digit,其中start为digit位数开始的数字,即
10
,
100
,
.
.
.
10,100,...
10,100,....
我们可以看出:
840
>
9
840>9
840>9,
(
840
−
9
)
>
180
(840-9)>180
(840−9)>180,
(
840
−
9
−
180
)
<
2700
(840-9-180)<2700
(840−9−180)<2700,故可以判断出n所在的数字num位数digit=3。又由于可知0-99对应了前189位,则要求的第840位相当于101-999的第(840-9-180-1)位,这里减去1是由于这里要将100开始算0。这里digit=3,所以
n
u
m
=
100
+
(
840
−
9
−
180
−
1
)
/
/
3
=
316
num=100+(840-9-180-1)//3=316
num=100+(840−9−180−1)//3=316;又知道这是100-999内的数,(840-9-180-1)%3即为num的第几位,即第2位(从0位开始),即为6.
P.S.图解参看这篇文章
code
class Solution:
def findNthDigit(self, n: int) -> int:
#思路:删减掉不需要的数字
if n<0: return -1
if n<10: return n
cnt = 9
start = 1
digit = 1
#确定位数
while cnt<n:
n -= cnt
digit += 1
start *= 10
cnt = 9*start*digit
#确定数字
num = start + (n-1)//digit
#确定第几位
num = str(num)
res = num[(n-1)%digit]
return int(res)