在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 中找到第 n 个数字。
注意:
n 是正数且在32位整数范围内 ( n < 2)。
示例 1:
输入:
3
输出:
3
示例 2:
输入:
11
输出:
0
说明:
第11个数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是0,它是10的一部分。其实相当于一串数字组成的字符串("12345678910111213141516"等无限长但小于计算机32位所表示位数),寻找指定第 n 个字符,例如这里的第二十三位字符是6。
思路:
区间 数字个数 字符数个数 字符数累积总和
1-9 9 9*1=9 9
10-99 90 90*2=180 180+9=189
100-999 900 900*3=2700 2700+189=2889
... 9 * 10^(位数-1) 数字个数* 位数 累积和
package com.loo;
public class FindNumber {
public static void main(String[] args) {
// 1 在 [1~9] 区间
System.out.println(findNumber(1));
// 11、23、24 在 [10~99] 区间
System.out.println(findNumber(11));
System.out.println(findNumber(23));
System.out.println(findNumber(24));
// 365、366、597、999 在 [100~999] 区间
System.out.println(findNumber(365));
System.out.println(findNumber(366));
System.out.println(findNumber(597));
System.out.println(findNumber(999));
}
public static int findNumber(int num) {
// 小于10的是数字本身
if (num <10) {
return num;
}
long n = num;
long size = 1;
long max = 9;
while (num > 0) {
// 判断数字在哪个段位区间
if (n - max * size > 0) {
n = n - max * size;
size ++;
max = max * 10;
} else {
int c = (int)(n / size);
int m = (int)(n % size);
// m == 0 说明正好是 num 的第 size 位(最后一个数字,如597最后一位就是7),注意这里需要 c - 1 才不越界到下一位
if (m == 0 ) {
return (int)(((long)Math.pow(10 , size-1) + c - 1)%10);
} else {
// 如果 m 不为 0 ,说明不是 num 的最后一位,可能是前面一位或者前面几位,这里以(size-10)表示
return (int)(((long)Math.pow(10 , size-1) + c)/((long)Math.pow(10 , size-m))%10);
}
}
}
return 0;
}
}