【LeetCode】400. 第N个数字(同剑指 Offer 44)

博客详细解析了如何在无限整数序列中找到第N个数字的方法,通过归纳法确定数字的位数、所在数字及数位位置,讨论了时间复杂度和空间复杂度,并提及该问题的解题思路和拓展思考。
摘要由CSDN通过智能技术生成

一、题目

在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …中找到第 n 个数字。

注意:
n 是正数且在32位整数范围内 ( n < 231)。

示例 1:

输入:
3

输出:
3

示例 2:

输入:
11

输出:
0

说明:11个数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是0,它是10的一部分。

二、解决

1、归纳法

思路:

为了下面推导方便,厘清一下几个概念:

  • 数位: 将 12345… 每一位称为数位,记为 n;
  • 数字: 将 11,12,13称为数字,记作 num;
  • 位数:10 是两位数, 999 是三位数,记为 digit;
  • 起始数字:每 digit 位数的起始数字(即:1,10,100,…),记为 start。
    1
    由上图知, d i g i t digit digit 位数的数位数量 c o u n t count count 计算公式为: c o u n t = 9 ∗ s t a r t ∗ d i g i t count = 9*start*digit count=9startdigit

根据上面分析,可将求解分解为三步(宏观到微观,逐层定位):

  1. 位数digit:确定 n n n 所在数字位数,记为 d i g i t digit digit
  2. 数字num:确定 n n n 所在数字,记为 n u m num num
  3. 数位 pos :稳定 n n n n u m num num 中的哪一数位,并返回结果。

下面逐步分析:
1.位数digit: 确定 n n n 所在数字的位数,记为digit

循环减去一位数、两位数、…、digit位数、…的数位数量count,直到count之和超出 n 。

2
2. 数字num:确定所求数位所在的数字

经过循环相减后,所求数位 在从数字start开始的第 [(n-1)/digit] 个数字中(start为第 0 个数字)。

num = start + (n-1/ digit

3

3. 数位pos:确定所求数位在 num 的哪一数位

数位在所求数字的第 (n-1) % digit 位。(首个数位为第 0 位,也为了与最后数组索引保存一致。)

4

[0, 9]这个区间,长度为9,每个数字只有1位,共有 9 ∗ 1 9*1 91个数字
[10, 99]这个区间,长度为90,每个数字只有2位,共有 90 ∗ 2 90*2 902个数字
[100, 999]这个区间,长度为900,每个数字只有3位,共有 900 ∗ 3 900*3 9003个数字

过程:区间–>具体数字–>数字特定位

代码:

class Solution {
    public int findNthDigit(int n) {
        int digit = 1;
        long start = 1;
        long count = 9;
        // 1. 区间
        while (n > count) { 
            n -= count;
            digit += 1;
            start *= 10;
            count = digit * start * 9;
        }
        // 2. 数字
        long num = start + (n - 1) / digit; 
        // 3. 数位
        return Long.toString(num).charAt((n - 1) % digit) - '0'; 
    }
}

时间复杂度: O ( l o g n ) O(logn) O(logn),求数位 n 对应数字 num 的位数 digit 最多循环 O ( l o g n ) O(logn) O(logn)次。
空间复杂度: O ( l o g n ) O(logn) O(logn),将 num 转化为字符串使用 O ( l o g n ) O(logn) O(logn) 时间。

2、思考

43 求1的数量,可以遍历数位;
44 求第n个数字,可以通过遍历位数,确定区间,再确定到数,再定位到数字。

这都是复杂问题拆解为简单问题的,然后分步骤解决。做菜也是一样,拆解为多个简单问题并解决,然后组合衔接起来就是一个相对复杂的问题。

延申:如何找到问题?如何找到多种解法&优劣?多种测试案例保证健壮性?

三、参考

1、面试题44. 数字序列中某一位的数字(迭代 + 求整 / 求余,清晰图解)
2、Just explain, no code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值