代码
class Solution {
public int findNthDigit(int n) {
int base = 1;//位数
int weight = 9;//权重
while(n>(long)base*weight){//300
n-=base*weight;
base++;
weight*=10;
}
//n=111 base=3 weight=900;
n--;
int res = (int)Math.pow(10,base-1)+n/base;
int index = n%base;
return String.valueOf(res).charAt(index)-'0';
}
}
思路(包懂嘟因为mikey都懂)
1. 确定 nnn 所在的位数段
-
初始化:
base = 1
表示当前数字段的位数(从 1 开始)。weight = 9
表示当前段所有数字占用的总位数。
-
循环条件:
n > base * weight
- nnn 比当前段所占的总位数大,说明 nnn 不在当前位数段。
- 减去当前段的总位数后,继续检查下一段。
-
更新规则:
- 减去当前段的总位数:
n -= base * weight
。 - 位数加 1:
base++
。 - 更新权重:
weight *= 10
(下一段的数字数量增加了 10 倍)。
- 减去当前段的总位数:
示例:当 n=300时,
- 初始:
base = 1, weight = 9
,剩余 n=300−9=291。 - 更新:
base = 2, weight = 90
,剩余 n=291−180=111。 - 更新:
base = 3, weight = 900
,此时 n=111,不再减去。
此时可以确定,n 位于 3 位数段(100 ~ 999)。
2. 定位到具体数字
在确定 nnn 位于当前位数段后:
- 进行
n--
操作,将索引调整为从 0 开始:- 这是因为自然序列是从 1 开始,而数字的位是从 0 开始计数的。
- 使用公式确定数字:
res = (int)Math.pow(10, base-1) + n / base
- Math.pow(10, base-1)表示当前段的起始数字。
- n/base表示 n超出当前段起始的完整数字个数。
- 两者之和 res 就是目标数字。
示例:当 n=111且 base=3时:
- 进行
n--
,得到 n=110。 res = 100 + 110 / 3 = 100 + 36 = 136
。
3. 提取数字中的具体位
最后一步是从计算得到的数字中提取 nnn 对应的位:
index = n % base
计算数字中的具体位索引。- 转换为字符串,提取对应字符:
String.valueOf(res).charAt(index) - '0'
。
示例:数字 136,索引 n=110,
- index=110%3=2。
- 对应数字 136 的第 2 位是 6。
因此返回结果 6。