在无限的整数序列 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)); } else { // 如果 m 不为 0 ,说明不是 num 的最后一位,可能是前面一位或者前面几位,这里以(size-10)表示 return (int)(((long)Math.pow(10 , size-1) + c)/((long)Math.pow(10 , size-m))); } } } return 0; } }