剑指 Offer 44. 数字序列中某一位的数字

 

思路:找规律

数字范围 数字位数 数字数量 数位数量
0-9 1 10 10
10-99 2 90 180
100-999 3 900 2700
…… …… …… ……
start-end digit 9*start 9*start*digit

  由此,要得到第n位对应的数字,需要分三步:

  1. 确定 n 所在数字 num 的位数 digit;

  记录当前数字位数对应的数位总和count,n 不断减去上一个位数的数位总和。

  当 n ≤ count 时,确定 n 所在数字 num 的位数 digit;

  2. 确定 num;

  记录当前数字位数对应的数字范围左边界 start,num = start + n / digit;

  3. 确定 n 是 num 中的哪一位,返回结果。

  n 在num中的位数等于 n % digit。

  将数字 num 转换成字符数组,使用charAt()-‘0’得到结果。

代码:

时间复杂度O(logn):

所求数位 n 对应数字 num 的位数 digit 最大为 O(logn) ;第一步最多循环 O(logn) 次;第三步中将 num 转化为字符串使用 O(logn) 时间;因此总体为 O(logn) 。

空间复杂度O(logn):

将数字 num 转化为字符串 str(num) ,占用 O(logn) 的额外空间。

class Solution {
    public int findNthDigit(int n) {
        //初始化
        if (n < 10)
            return n;
        int digit = 1;//位数
        long start = 1;//每个digit开始的数字
        long count = 10;//在digit位数中数位的数量,如1位数有10个(从0开始),2位数有90个
        while (n > count) {
            n -= count;//减去上一个位数的数位总和
            digit++;
            start *=10;
            count = 9 * start * digit;
        }
        //求n所在数字num
        long num = start + n / digit;//此时的n减去了小于它的位数总和
        int i = n % digit;//得到n在num中的位数
        return Long.toString(num).charAt(i) - '0';//long型转string,charAt得到第i位字符型数字,减‘0’得到对应数字
    }
}
posted @ 2021-02-28 23:55  zjcfrancis  阅读(49)  评论(0编辑  收藏  举报