📅  最后修改于: 2023-12-03 15:27:57.693000             🧑  作者: Mango
在一个无限的整数序列 1,2,3,4,5,6,7,8,9,10,11,...
中,我们想要找到第 k
位数字。需要注意的是,k
可能非常大且由多位数字组成。
本题目的主题为“计数第K位为N的数字”,要求在整数序列中找到第 k
位数字是 N
的数字。例如,当 k = 11
时,答案为 0
。
为了更好地解决本问题,我们可以通过以下几个步骤:
确定第 k
位数字所在的数字段(由数字个数相同的数字组成的区间)。
对于各位数字相同的数字,它们的个数一定是与它们的位数相关的,例如一位数有 9 个,两位数有 90 个,三位数有 900 个……因此我们可以根据 k
的大小确定第 k
位数字在哪个数字段中。
例如 k = 11
,由于前 9 个数字都只有一位,因此第 11 个数字一定是两位数。因此我们已经确定第 k
位数字所在的数字段为 10 ~ 99
。
确定第 k
位数字所在的具体数字。
已经确定了第 k
位数字所在的数字段,接下来只需要确定第 k
位数字在该数字段中的具体位置即可(即第几个数字)。例如对于数字段 10 ~ 99
,我们需要确定第 k
位数字在其中的第 x
个数字,然后确定该数字的第 y
位数字即为我们要求的结果。
对于数字段 10 ~ 99
,第 k
位数字在其中的第 x
个数字可以通过以下公式计算得到:
x = k - 9 1 <= k <= 9
x = k - 9 - 2 * 90 10 <= k <= 189
x = k - 9 - 2 * 90 - 3 * 900 190 <= k <= 2889
...
通过公式计算得到 x
后,可以轻松地找到该数字的第 y
位数字。
确定第 k
位数字所在的具体位置。
确定第 k
位数字所在的具体位置(即在该数字的哪一位)也是本问题的关键之一。根据上面的步骤 2,我们已经确定了第 k
位数字所在的数字段和该数字的第 y
位数字,接下来只需要根据 y
的值再进行简单的运算即可。
对于一个 m
位数 num
,我们将第 k
位数字所在的位置记为 pos
,那么 pos
可以通过以下公式计算得到:
pos = m - y + 1
例如当 num = 987654321
、y = 3
时,第 3
位数字在 num
中的具体位置为 7
。
有了上述三个步骤,我们就可以轻松地解决本问题了。下面是本题的 Python 代码实现:
def find_kth_number(n: int, k: int) -> int:
def get_count(num: int) -> int:
"""
计算 num 的个数,例如 num = 10 时返回 9,num = 100 时返回 180
"""
count = 0
m = 1
while m <= n:
count += min(num, n // m)
m *= 10
return count
# 二分查找确定第 k 位数字所在的数字段
left, right = 1, n
while left < right:
mid = (left + right) // 2
count = get_count(mid)
if count < k:
left = mid + 1
else:
right = mid
# 确定第 k 位数字所在的具体位置
num = str(left)
y = k - get_count(left-1)
pos = len(num) - y + 1
return int(num[pos-1])
最后,我们来进行一些简单的测试,验证以上代码的正确性。例如:
find_kth_number(9, 1) # 1
find_kth_number(99, 11) # 0
find_kth_number(1234, 345) # 4
以上就是本题的详细介绍。本题中的二分查找和位数计算技巧可以应用到其他类似的问题中,希望对大家有所帮助。