《剑指offer—面试题44:数字序列中某一位的数字》
注明:仅个人学习笔记
在看不懂书上解题思路的情况下,建议阅读以下博客中的解题思路:
https://blog.csdn.net/m0_37950361/article/details/80633177
代码是参考书上进行实现:
/**
*
* 数字序列中某一位的数字,序列位数从0开始
*
* @param index:
* 表示要查询数字序列中的第多少位数,比如查询数字序列第1001位数是多少
* @param digits:
* 表示处于哪一位,个位?十位?百位?依次类推
*
*
*/
public class InNumberSequenceSomePositinoNumber44
{
public int digitAtIndex(int index)
{
// index<0,数字序列不存在这样的位数
if (index < 0)
{
return -1;
}
int digits = 1;
while (true)
{
int numbers = countOfInteger(digits);
// numbers * digits
// 如果数字序列的位数从1开始
// 表示每一类数的范围,个位,1位数是0-9,共占数字序列10位,index:1-10
// 十位,2位数是10-99,共占数字序列90*2=180位,index:11-190
// 百位,3位数是100-999,共占数字序列900*3=2700位,index:191-2890
// 后面以此类推
// 从此处判断出第index位,这个数属于哪位数
if (index < numbers * digits)
{
return digitsAtIndex(index, digits);// 函数最终返回值
}
index -= digits * numbers;// index减去不可能的序列位数,比如第1001位,首先减去1位数的10个,再减去2位数的90*2=180个,最终得到实际构成3位数的位数有多少
digits++;
}
}
// 当我们知道要找的那一位数字位于某m位数之中,后,就利用如下函数找出那一位数字
private int digitsAtIndex(int index, int digits)
{
// index / digits表示实际构成digits位数的个数,+,上digits位数的其实值,就得到的第index所处的实际digits位数的实际数字,
// 比如第1001位,实际3位数是370,然后确定第1001到底是370中的哪个数字,从0开始
int number = beginNumber(digits) + index / digits;
int indexFromRight = index % digits;
// int indexFromRight = digits - index % digits;//这里代码,i就得是从1开始
for (int i = 0; i < indexFromRight; i++)
{
number /= 10;
}
return number % 10;
}
// 在上述函数中,我们需要知道m位数字的第一个数字。
// 第一个1位数是0,第一个2位数是10,第一个三位数是100。。。。。。
private int beginNumber(int digits)
{
if (digits == 1)
{
return 0;
}
return (int) Math.pow(10, digits - 1);
}
// 得到m位的数字,总共有多少个
// 个位数有10个,十位数有90个,百位数有900个
private int countOfInteger(int digits)
{
if (digits == 1)// 如果是个位数,那就有10个数字0-9
{
return 10;
}
int count = (int) Math.pow(10, digits - 1);// 10的多少次方
return 9 * count;
}
public static void main(String[] args)
{
InNumberSequenceSomePositinoNumber44 n = new InNumberSequenceSomePositinoNumber44();
System.out.println(n.digitAtIndex(1001));
}
}