描述

剑指offer JZ44 数字序列中某一位的数字
数字以 0123456789101112131415… 的格式作为一个字符序列,在这个序列中第 2 位(从下标 0 开始计算)是 2 ,第 10 位是 1 ,第 13 位是 1 ,以此类题,请你输出第 n 位对应的数字。

方法一:通过减去位数计算

思路:由于数字之间的差异点是在位数,所以我们可以把位数不同的数字分组,计算出这个位数所有数字的位数个数,然后计算n对应的位数区间,知道了n在哪个位数区间就可以定位到具体数字。
实现技巧 :1-9,一位数总共9个,10-99,两位数一共90个,100-999,三位数一共900个。可以发现,同一位数的个数=这个位数的起始数字9,比如二位数的个数 =109=90。得到数字的个数之后,再将个数乘以位数,即可得到这个位数的所有位数之和,比如两位数位数和就等于90*2=180;
代码实现与相应解释说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.*;
public class Solution {
public int findNthDigit (int n) {
//记录当前位数
int digit = 1;
//记录当前位数区间的起始数字
long start = 1;
//记录当前区间总共有多少位数
long sum = 9;
//将n定位在某个位数的区间中
//当n大于这个区间时,则减去这个区间的位数和,便于判断是否在下一区间,
// 并且便于在区间中准确定位
while (n > sum) {
n -= sum;
start *= 10;
digit++;
//该区间的总共位数
sum = 9 * start * digit;
}
//定位n在哪个数字上
//因为此处多算了一次start这个数字,所以要-1;
String num = "" + (start - 1 + Math.ceil((double)n / digit) );
//定位n在数字的哪一位上
//常规逻辑应当想到,用n对位数取余来确定n在一个数字的第几位,比如余数为1,就在第一位,
//但是我们需要的是坐标,坐标是从0开始的,所以需要经过如下数学处理
//余数为1,index为0,余数为2,index为1.......只需要将所得结果-1。余数为0是特殊情况,index为位数-1
int index = (n % digit == 0? digit : n % digit) -1 ;
return Integer.parseInt(num.charAt(index)+"");
}
}

方法二:位数补零法

思路:将低位数数字的位数,全部补成高位数。比如n在两位数区间,则需要将一位数补位成00,01,02……;若n在三位数区间,则需要将一位数补位为000,001,002……,将两位数补位为010,011,012……;并且n需要加上相应补位的位数,便于判断。
代码实现与相应解释说明:
说明:代码中的Math.pow(10,digit) (digit为当前最高位数),代表在当前digit下的数字个数。比如digit为2, 代表两位数,Math.pow(10,2)=100,当前有100个数字。

public class Solution {
    public int findNthDigit (int n) {
      //记录位数
      int digit = 1;
      //关键点,为什么是n需要+1。因为在没有补位时,n的数字是没有把0计算在内的(比如3代表1,2,3,并不是0,1,2)。
      //但是在n加上Math.pow(10,digit)时,是会给0补位的。比如不加1,对3补位就代表数字0,01,02,03,0处少了一个0.+1就是为
      //了把这个0补上,便于之后的计算
      n += 1;
      //寻找n在哪个位数,并把低位补充
      while (digit * Math.pow(10, digit) < n) {
        n += Math.pow(10,  digit);
        digit++;
        }
        //因为还有0,所以要减去1
      String num = (n / (double)digit - 1)+ ""
       //定位n在数字的哪一位上
       //常规逻辑应当想到,用n对位数取余来确定n在一个数字的第几位,比如余数为1,就在第一位,
       //但是我们需要的是坐标,坐标是从0开始的,所以需要经过如下数学处理
       //余数为1,index为0,余数为2,index为1.......只需要将所得结果-1。余数为0是特殊情况,index为位数-1
      int index = (n % digit == 0 ? digit : n % digit) - 1;
      return Integer.parseInt(num.charAt(index)+"");
    }
}