题目描述
// 44. 数字序列中某一位的数字
// 力扣
// 数字以0123456789101112131415…的格式序列化到一个字符序列中。
// 在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19
// 位是4,等等。
// 请写一个函数,求任意第n位对应的数字。
题解
// 1.先求n所在的数字属于几位数,2.后求n所在的数字num,3.最后求n在数字num的第几位
// 如n=11,我们将
// 1:先求n所在的数字属于2位数
// 2:后求n所在的数字为10,
// 3:最后求得n在数字10的第二位,即目标为数字0。
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:35.3 MB, 在所有 Java 提交中击败了33.22%的用户
class Solution {
public int findNthDigit(int n) {
// 位数记录,如11为2位数,123为3位数。初始化digit为1
int digit = 1;
// 当前以位数digit所开始的数字,2位数开始的数字为10,1位数
// 开始的数字为1(0不算1位数)
long start = 1;
// 在当前位数digit下包含的数字数量。由于位数digit初始化为1,
// 所以位数为1的数字总共有1 2 3 4 5 6 7 8 9,共9个数字。
long count = 9;
// 先求n所在的数字num的位数digit
// 如果位数数字总数count少于n,执行循环
while (count < n) {
n -= count; // n减去当前位数数字总数count,若n=15,更新为n=15-9=6
digit++; // 位数更新
start *= 10; // 位数digit开始的数字start根据位数进行更新
count = 9 * start * digit; // count根据start和digit进行更新
}
// 若n=15更新为了n=6。位数digit同时可以理解为所在位数区间内
// 所有数字的长度,digit=2,说明所在位数区间内所有数字长度都为2,
// 而n-1表示从start(start=10)数字第一位开始,到达n=6位置的数位长度
// (所经历的位)即1->0->1->1->1->2,长度为5。
// 那么(n-1)/digit即可得到数字本身从start开始,在位数区间的数字长度(所经历的数)
// 即10->11->12,长度为2。此时再加上start即可得到n所在的数字num
long num = start + (n - 1) / digit;
// 求n所在数字的第几位
// n-1表示从start(start=10)数字第一位开始,到达n=6位置的数位长度
// 我们直接看这个长度能不能被digit整除即可
int i = (n - 1) % digit;
return Long.toString(num).charAt(i) - '0';
}
}