目录
题目描述
数字以 0123456789101112131415...n (这是一个0~n排列)的格式序列化到一个字符序列中,在这个字符序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写出一个函数,求任意第n位对应的数字。
测试用例
- 功能测试(输入10、190、1000等)
- 边界值测试(输入0、1等)
题目考点
- 考察应聘者优化的激情和能力。最原始的方法大部分应聘者都能想到。当面试官提示还有更快的方法之后,应聘者千万不要轻易放弃尝试。必要的时候可以要求面试官给出提示。
- 考察应聘者面对复杂问题的分析能力,可以通过分析具体例子一步步找到通用的规律。
解题思路
以第1001位数字7为例 步骤1:首先确定该数字是属于几位数的; 如果是一位数,n<9;如果是两位数,n<9+902=189;如果是三位数,n<189+9003=2889; 说明是三位数。(这里有个循环) 步骤2:确定该数字属于哪个数。100+(1001-190)/3= 370。 步骤3:确定是该数中哪一位。1001-190-(370-100)*3 = 1,所以位于“370”的下标为1的位置,即数字7
自己解题
package Sword;
public class Serialization {
public static void main(String[] args) {
Serialization serialization = new Serialization();
System.out.println(serialization.digitAtIndex(19));
}
// ----求数字序列中某一位的数字--------------------
public int digitAtIndex(int index) {
if (index < 0) {
return -1;
}
int digits = 1;
while (true) {
int numbers = countOfIntegers(digits); //功能函数: m位数字的总数
if (index < numbers * digits) {
// 在m位数的大范围内,
return digitAtIndex(index, digits);// 功能函数,在m位数大范围中精确找到这个数字
}
// 更新下标和位数
index -= numbers * digits;
digits++;
}
}
// ----知道要找的那位数字位于某m(digits)位数中后,使用下面的函数精准找出该数--------
public int digitAtIndex(int index, int digits) {
// 如 100 + 811/3, 即 起始 + 下标整除m,
int number = beginNumber(digits) + index / digits;
// 通用方法:取number中的从左到右第x位,就是从右到左的第 digits-x 位
int indexFromRight = digits - index % digits;
for (int i = 1; i < indexFromRight; ++i) {
// 结果就是取number中的第 index % digits 位数,比如 811 % 3 = 1 ,取370的第1位数,注意是从第0位开始
number /= 10;
}
return number % 10;
}
// -----求出m位数字的个数--------------------
public int countOfIntegers(int digits) {
if (digits == 1) {
return 10;
}
int count = (int) Math.pow(10, digits - 1);
return 9 * count;
}
// -----求m位数的第一个数字-------------------
public int beginNumber(int digits) {
if (digits == 1) {
return 0;
}
return (int) Math.pow(10, digits - 1);
}
}