1. 题目
数字以0123456789101112131415······的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第19位是4,等等。请写一个函数,求任意第n位对应的数字。
2. 解题思路
2.1 常规思路
从0开始枚举每个数字,每枚举一个数字的时候,求出该数字是几位数(如15是2位数,9323是4位数);
把该数字的位数和前面所有数字的位数的位数累加。
比较位数之和与输入的数字n,若小于等于这个n,则继续往下枚举数字;
若大于n,那么第n位数字一定是所枚举的这个数字中的某一位,再从该数字中找到对应的那一位。
很明显,这个思路需要一个数字一个数字的往下递推,每个数字都要去判断。
2.2 书中的思路
举个例子来分析,找到思路。例如,序列中的第1001位是什么?
序列中的1位数是 0~9 ,共10个。1001 大于 1 * 10 ,因此,这个数一定在0 ~ 9 之后;
序列中的2位数是 10 ~ 99 ,共90个。(1001 - 1 * 10) = 991 大于 2 * 90,因此,这个数一定在 10 ~ 99 之后;
序列中的3位数是 100 ~ 999,共900个。(1001 - 1 * 10 - 2 * 90) = 811 小于 3 * 900,因此,这个数一定在 100 ~ 999 之间;
步骤
1.确定所求数位的所在数字的位数
2.确定所求数位所在的数字
3.确定所求数位在 numnum 的哪一数位
3. 代码实现
这里只写书上这种思路的代码实现。
def digit_at_index(index):
"""
:param index: 格式化序列中的第几个数字,从0开始计数
:return int: 该index对应的数字
"""
if index < 0:
return -1
digit = 1
while True:
numbers = count_of_integers(digit)
if index < numbers * digit: # 这些位数为digit的数字总共占据了多少位置
return find_digit(index, digit)
index -= digit * numbers
digit += 1
return -1
def count_of_integers(digit):
"""
根据输入的数字,判断digit位的数字有多少个
:param digit: 数字的位数
:return int:
"""
if digit == 1:
return 10
return 9 * pow(10, digit-1) # 效率较下行方式更高
#return 9 * (10 ** (digit-1))
def find_digit(index, digit):
"""
:param index: 在格式化序列中的第几个数字
:param digit: 几位数字,就是第index的数字是digi位数字中的某一个
:param int: 根据这个两个条件得出此index对应的数字是多少
"""
number = begin_number(digit) + index // digit
# index对应的数字应该是number这个数中从右往左的第index_from_right这个数字
index_from_right = digit - index % digit
for i in range(1, index_from_right):
number //= 10
return number % 10
def begin_number(digit):
"""
获取digit位数字的中的第一个数字是多少
:param digit: 数字位数
:return int: 在digit位数字中的第一个数字
"""
if digit == 0:
return 0
return pow(10, digit-1)
#return 10 ** (digit-1)
3.2 精简版
class Solution:
def findNthDigit(self, n: int) -> int:
digit, start, count = 1, 1, 9
while n > count: # 1.确定所求数位的所在数字的位数
n -= count
start *= 10
digit += 1 # 数字的位数
count = 9 * start * digit
num = start + (n - 1) // digit # 2.确定所求数位所在的数字
return int(str(num)[(n - 1) % digit]) # 3.确定所求数位在 numnum 的哪一数位
作者:jyd
链接:https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/solution/mian-shi-ti-44-shu-zi-xu-lie-zhong-mou-yi-wei-de-6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
4. 总结
有没有发现最近的几道题都是,找出规律才能得到最好的算法,一般一开始想到的算法,复杂度过高,效率不太行。
5. 参考文献
[1] 剑指offer丛书
[2] 剑指Offer——名企面试官精讲典型编程题