官方题解说明---剑指offer-JZ44 数字序列中某一位的数字

题目连接:数字序列中某一位的数字_牛客题霸_牛客网 (nowcoder.com)

官方题解说明---剑指offer-JZ44 数字序列中某一位的数字_第1张图片

官方题解:

import java.util.*;
public class Solution {
    public int findNthDigit (int n) {
        //记录n是几位数
        int digit = 1;
        //记录当前位数区间的起始数字:1,10,100...
        long start = 1; 
        //记录当前区间之前总共有多少位数字
        long sum = 9; 
        //将n定位在某个位数的区间中
        while(n > sum){
            n -= sum;
            start *= 10; 
            digit++; 
            //该区间的总共位数
            sum = 9 * start * digit;
        }
        //定位n在哪个数字上
        String num = "" + (start + (n - 1) / digit);
        //定位n在数字的哪一位上
        int index = (n - 1) % digit;
        return (int)(num.charAt(index)) - (int)('0');
    }
}

这个问题涉及到了一个有趣的数学规律,关键在于确定给定的数字 n 落在哪个数字区间内,以及它是那个数字的哪一位。这个解法的基本思路是先确定 n 对应的是几位数的数字,然后找到具体的数字,最后确定是该数字的哪一位。下面我将详细解释这个过程:

  1. 确定位数区间

    • 我们知道,1位数有9个(1-9),共有9位;

    • 2位数有90个(10-99),共有90*2=180位;

    • 3位数有900个(100-999),共有900*3=2700位;

    • 以此类推。

    这个解法首先计算 n 落在这些区间中的哪一个。例如,如果 n 是172,则它会落在2位数的区间,因为172超过了1位数区间的长度(9),但不超过1位数和2位数区间总长度(9+180=189)。

  2. 计算起始数字和区间长度

    • 每个区间的起始数字是1、10、100等,这些数字是以10的幂递增的。

    • 区间长度可以用 9 * start * digit 计算,其中 start 是区间的起始数字,digit 是当前区间的数字位数。

    在上面的例子中,2位数的起始数字是10,区间长度是180。

  3. 定位具体数字

    • n 被定位到某个区间后,减去前面所有区间的长度,得到的新 n 就是在当前区间的索引。

    • 然后,用 (n - 1) / digit 加上区间的起始数字,就可以找到具体的数字。这里 n - 1 是因为索引是从0开始的。

    在上面的例子中,新 n 是172 - 9 = 163,表示172是2位数区间的第163位。所以,具体数字是 10 + (163 - 1) / 2 = 91

  4. 定位数字的具体一位

    • 最后,使用 (n - 1) % digit 确定 n 是这个具体数字的哪一位。

    在上面的例子中,163 % 2 = 1,表示172是数字91的第1位(从0开始计数),所以答案是9。

你可能感兴趣的:(数据结构与算法分析,java,算法,数据结构,笔记)