题目:数字以 012345678910111213141516171819…的格式序列化到一个字符序列中。在这个序列中第 1 位 是 0 ,第五位是 4 , 第 11 位是 1 ,我们现在要求第 n 位对应的数字。
思路:
最简单的方法是从 0 开始,累加数字,最终刚好得到第 n 位数字,或者刚好比 n 多的数字,再求对应数字。但是这样时间复杂度较高,也没有合理的利用数字规律,显然不是最佳的方法。
接下来我们考虑数字顾虑,明显 前 10 个数是 0123456789 ,这 10 数都是 个位有数字,而 10~99 这 90 个数每个数有两位数: 十位和个位,一共有 90*2 = 180 个数,100~999 这 900 个数每个数有三位数: 百、十、个 位 ,一共有 2700个数,1000~9999 这9000个数每个数有四位,一共 36000 个数……以此类推,我们可以找出 第 n 个数落在那部分中。
用一个具体的例子来说明:比如我们现在找第 3500 个数对应的哪个数,因为 3500 > 10 ,所以不在 0~9 中,3500 > (180 + 10 ),所以不在 10~99中,3500 > (2700 + 180 + 10 ),所以不在 100~999 中,3500 < (36000 + 2700 + 180 + 10 ),所以 第 3500 个数落在 1000~9999 中。我们现在已经找出第 n 个数在哪段数中,接着就是找出对应的那个数字。3500 - (2700 +180 + 10) = 610,1000~9999 中每个数有四位,所以对应的数是 610/4 = 152 余 2,152 余 2 代表什么呢?代表 1000~9999 这些数中的 第 152 个数的 第二位数字(从高位开始),所以对应的就是 1152 的第二个数字 1 。我们再假设一种情况,就是 刚好整除没有余数的情况,比如我们假设的是 3498 ,有前面的计算可知最后得到的 608/4 = 152 ,那么 它表示的就是 1000~9999 这些数中第 152 个数 1151 (因为第一个数是 1000)的最后一位数即 1。
接下来就是具体的实现了,废话不说了直接上代码:
import java.util.Scanner;
/**
*
* @author luzi
* 2017-5-30
*/
public class findNum0fN {
public static void main(String args[]){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
int n = scan.nextInt();
System.out.println(getNum(n));
}
}
private static int getNum(int n) {
// TODO Auto-generated method stub
if(n <= 10)
return (n - 1)%10;
int p = 10;
int count = 1;
int temp = 0;
//找出第 n 个数在哪个 数字区间中
while(p < n){
temp = (int) (Math.pow(10, count)*9*(++count));
p += temp;
}
int N = n - (p - temp);
int num = (int) Math.pow(10, count - 1) + (N/count) - 1;
if(N%count == 0){
System.out.println(num);
return num%10;
}
else{
num++;
System.out.println("对应的数字是:" + num);
int tp = (int) Math.pow(10, count - N%count);
return (num/tp)%10;
}
}
}