[剑指-Offer] 44. 数字序列中某一位的数字(数学、思维、巧妙解法)

1. 题目来源

链接:数字序列中某一位的数字
来源:LeetCode——《剑指-Offer》专项

2. 题目说明

数字以 0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第 5 位(从下标 0 开始计数)是 5,第 13 位是 1,第 19 位是 4,等等。

请写一个函数,求任意第 n 位对应的数字。

示例 1:

输入:n = 3
输出:3

示例 2:

输入:n = 11
输出:0

限制:

  • 0 <= n < 2^31

3. 题目解析

方法一:数学+思维+巧妙解法

这道题的关键就是要找出第 N 位所在的数字,然后可以把数字转为字符串,这样直接可以访问任何一位。分析自然数序列和其位数的关系:

  • 前 9 个数都是 1 位
  • 10 到 99 总共 90 个数字都是两位
  • 100 到 999 这 900 个数都是三位的

那么这就很有规律了,可以定义个变量 cnt,初始化为 9,然后每次循环扩大 10 倍,再用一个变量 len 记录当前循环区间数字的位数,另外再需要一个变量 start 用来记录当前循环区间的第一个数字,n 每次循环都减去 len * cnt (区间总位数),当 n 落到某一个确定的区间里了,那么 (n - 1) / len 就是目标数字在该区间里的坐标,加上 start 就是得到了目标数字,然后我们将目标数字 start 转为字符串,(n - 1) % len 就是所要求的目标位,考虑 int 溢出问题,就干脆把所有变量都申请为long long 了。

参见代码如下:

// 执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :8.3 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int findNthDigit(int n) {
        long long len = 1, cnt = 9, start = 1;
        while (n > len * cnt) {
            n -= len * cnt;
            ++len;
            cnt *= 10;
            start *= 10;
        }
        start += (n - 1) / len;
        string t = to_string(start);
        return t[(n - 1) % len] - '0';
    }
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值