【LeetCode】剑指44——数字序列中某一位的数字(难度:中等)

【LeetCode】剑指44——数字序列中某一位的数字(难度:中等)

题目描述

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

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

  1. 示例 1:
    输入:n = 3
    输出:3

  2. 示例 2:
    输入:n = 11
    输出:0

限制:0 <= n < 231

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

首先是如果0≤n≤9,那么直接返回n即可。如果大于9,则可以进行后续的处理

我们知道有0~9一共10个一位数,从两位数开始,每个多位数都有90(两位数)、900(三位数)、9000(四位数)…个数字。这样可以先把n减去10,然后构造一个循环:不断地减去90×2、900×3、9000×4…,并用一个变量记录位数,直到n即将被减成负数,循环终止

上面步骤确定了第n个数字是几位数下的数字,现在确定具体是哪一个数字:把当前的n整除当前位数即为偏移量,如果是三位数,就拿100加上这个偏移量,如果是四位数,就拿1000加上这个偏移量,即可得到具体的数字

然后就是确定该数字的第几位了:当前n对当前位数取余即可

以一个具体例子说明一下,假定n=444

  1. 其不在[0, 9]内,进行后续操作
  2. 先减去10,n=434,初始化当前位数count=2,初始化即将要减去的数字num=90
  3. 进入循环,循环终止条件可以为while(n>0),也可以为while(true)
  4. 434-90×2=254,仍然n≥0,此时位数count+1=3,要减去得数字num×10=900
  5. 254-900×3<0,循环终止
  6. 先对num / 9=100,即是以100为基,然后计算偏移量
  7. num / count = 254 / 3 = 84,即偏移量为84,也就是说当前数字应该为100+84=184
  8. 然后确定第几位数:num % count = 254 % 3 = 2,也就是第2位数(下标从0开始),即254的“4”

代码详解

class Solution {
    public int findNthDigit(int n) {
        if(n >= 0 && n <= 9) { // 0~9直接返回即可
            return n;
        }
        // 循环前的准备工作
        n -= 10; // 先减去一位数的个数10
        int count = 2; // 至少为两位数
        long num = 90; // 两位数对应90个,注意这里一定用long,保证long*count不会越界
        // 开始循环
        while(n > 0) {
            if(n - num * count >= 0) { // 注意是≥0
                n -= (num * count);
                ++count; // 位数+1
                num *= 10; // 90、900、9000...
            } else {
                break;
            }
        }
        num /= 9; // 获取基数,三位数对应100,四位数对应1000...
        num += (n / count); // 加上偏移量获取对应的数字
        char[] cs = String.valueOf(num).toCharArray(); // 对应的数字按位数拆分
        return cs[n % count] - '0'; // 返回第 n%count 位的数字
    }
}

注意点

  1. 判断条件n - num * count >= 0,这里是≥0,等于0代表是当前count位数的首个数字
  2. num要用long进行修饰,确保num与count进行相乘后不会因越界而导致计算出错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值