📜  计数第K位为N的数字(1)

📅  最后修改于: 2023-12-03 15:27:57.693000             🧑  作者: Mango

计数第K位为N的数字

在一个无限的整数序列 1,2,3,4,5,6,7,8,9,10,11,... 中,我们想要找到第 k 位数字。需要注意的是,k 可能非常大且由多位数字组成。

本题目的主题为“计数第K位为N的数字”,要求在整数序列中找到第 k 位数字是 N 的数字。例如,当 k = 11 时,答案为 0

为了更好地解决本问题,我们可以通过以下几个步骤:

  1. 确定第 k 位数字所在的数字段(由数字个数相同的数字组成的区间)。

    对于各位数字相同的数字,它们的个数一定是与它们的位数相关的,例如一位数有 9 个,两位数有 90 个,三位数有 900 个……因此我们可以根据 k 的大小确定第 k 位数字在哪个数字段中。

    例如 k = 11,由于前 9 个数字都只有一位,因此第 11 个数字一定是两位数。因此我们已经确定第 k 位数字所在的数字段为 10 ~ 99

  2. 确定第 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 位数字。

  3. 确定第 k 位数字所在的具体位置。

    确定第 k 位数字所在的具体位置(即在该数字的哪一位)也是本问题的关键之一。根据上面的步骤 2,我们已经确定了第 k 位数字所在的数字段和该数字的第 y 位数字,接下来只需要根据 y 的值再进行简单的运算即可。

    对于一个 m 位数 num,我们将第 k 位数字所在的位置记为 pos,那么 pos 可以通过以下公式计算得到:

    pos = m - y + 1
    

    例如当 num = 987654321y = 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

以上就是本题的详细介绍。本题中的二分查找和位数计算技巧可以应用到其他类似的问题中,希望对大家有所帮助。