剑指Offer_#44_数字序列中某一位的数字

剑指Offer_#44_数字序列中某一位的数字

Contents

题目

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

注意:这里的题目和测试用例不同,测试用例中数字序列是从1开始不是从0开始,所以应该从1开始来做

示例 1:

输入:n = 3
输出:3

示例 2:

输入:n = 11
输出:0

限制:

0 <= n < 2^31

思路分析

最直接的思路

从1开始遍历(枚举)正整数,访问到每个数字的时候把当前数字的位数累加到一个计数变量中,直到这个计数变量大于等于n,说明要找的第n位就在当前枚举到的数字中,然后在这个数字当中找到我们想要的那一位。
但是这样做是时间超限的。

观察规律

和上一题一样,这一题也是属于观察规律题,通过找到数学规律来代替暴力搜索,降低时间复杂度。
这一题的规律如下:

数字范围 位数 个数 总位数
1~9 1 9 9
10~99 2 90 180
100~999 3 900 2700
从start开始 digit 9 * start count = 9 *start * digit

算法分为三步:

  1. 根据上述规律,循环计算每个数字范围内数字位数的countn减去count,直到n < count,说明要找的数就在当前范围内
  2. 寻找第n位数所在数字,从start开始,增加(n-1)/digit
  3. 寻找第n位在数字中的位置,应该是(n-1)%digit

解答

class Solution {
    public int findNthDigit(int n) {
        //题目和测试用例不符,测试用例是从1开始的
        long start = 1;
        long count = 9;
        int digit = 1;
        //1.寻找第n位所在的数字区间(即确定start,digit)
        while(n > count){
            n -= count;
            start *= 10;
            digit += 1;
            count = 9*digit*start;
        }
        //2.定位第n位所在的数字
        long num = start + (n - 1) / digit;
        //3.定位第n位在数字里边的第几位
        return Long.toString(num).charAt((n - 1) % digit) - '0';
    }
}
posted @ 2020-07-16 11:02  Howfar's  阅读(181)  评论(0编辑  收藏  举报