问题
给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …] 中找出并返回第 n 位数字。
示例1:
输入:n = 3
输出:3
示例 2:
输入:n = 11
输出:0
解释:第 11 位数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, … 里是 0 ,它是 10 的一部分。
思路:找规律
我们通过观察,可以发现以下规律:
对于找第 n 位对应的数字,主要分为3步
- 首先确定n是上面规律中第几位(类)数digits的第几个数据,这一部分用下面的while循环实现;
- 然后确定这个对应的数的数值 target;
- 最后确定返回值是 target 中的哪个数字。
举个例子:
比如输入的 n 是 365:
经过第一步计算我们可以得到第 365 个数字表示的数是三位数,n=365−9−90×2=176,digtis = 3。这时 n=176 表示目标数字是三位数中的第 176 个数字。
我们设目标数字所在的数为 number,计算得到 number=100+176/3=158,idx 是目标数字在 number 中的索引,如果 idx = 0,表示目标数字是 number - 1 中的最后一个数字。
根据步骤2,我们可以计算得到 idx = n % digits = 176 % 3 = 2,说明目标数字应该是 number = 158 中的第二个数字,即输出为 5。
代码
public int findNthDigit(int n) {
int base = 1; //表示第几位数的第一个值
int digits = 1;//表示第几位
while (n > base * 9 * digits) {
n -= (base * 9 * digits);
base *= 10;
++digits;
}
/* --n为下面使用String获取索引位置的数,
因为取余和除法计算序数”都是zero-based的算子,
而我们在while后只能得到一个one-based的序数(本质是因为题目输入是one-based,
你也可以把这个自减放到最开头,结果是一样的)*/
--n;
return getIndexDigit(base + n / digits, n % digits);
}
private int getIndexDigit(int target, int index) {
//此处 - '0' 看AIISC字符集
return String.valueOf(target).charAt(index) - '0';
}