题目描述
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
-
示例 1:
输入:n = 3
输出:3 -
示例 2:
输入:n = 11
输出:0
限制:0 <= n < 231
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
首先是如果0≤n≤9,那么直接返回n即可。如果大于9,则可以进行后续的处理
我们知道有0~9一共10个一位数,从两位数开始,每个多位数都有90(两位数)、900(三位数)、9000(四位数)…个数字。这样可以先把n减去10,然后构造一个循环:不断地减去90×2、900×3、9000×4…,并用一个变量记录位数,直到n即将被减成负数,循环终止
上面步骤确定了第n个数字是几位数下的数字,现在确定具体是哪一个数字:把当前的n整除当前位数即为偏移量,如果是三位数,就拿100加上这个偏移量,如果是四位数,就拿1000加上这个偏移量,即可得到具体的数字
然后就是确定该数字的第几位了:当前n对当前位数取余即可
以一个具体例子说明一下,假定n=444
- 其不在[0, 9]内,进行后续操作
- 先减去10,n=434,初始化当前位数count=2,初始化即将要减去的数字num=90
- 进入循环,循环终止条件可以为while(n>0),也可以为while(true)
- 434-90×2=254,仍然n≥0,此时位数count+1=3,要减去得数字num×10=900
- 254-900×3<0,循环终止
- 先对num / 9=100,即是以100为基,然后计算偏移量
- num / count = 254 / 3 = 84,即偏移量为84,也就是说当前数字应该为100+84=184
- 然后确定第几位数:num % count = 254 % 3 = 2,也就是第2位数(下标从0开始),即254的“4”
代码详解
class Solution {
public int findNthDigit(int n) {
if(n >= 0 && n <= 9) { // 0~9直接返回即可
return n;
}
// 循环前的准备工作
n -= 10; // 先减去一位数的个数10
int count = 2; // 至少为两位数
long num = 90; // 两位数对应90个,注意这里一定用long,保证long*count不会越界
// 开始循环
while(n > 0) {
if(n - num * count >= 0) { // 注意是≥0
n -= (num * count);
++count; // 位数+1
num *= 10; // 90、900、9000...
} else {
break;
}
}
num /= 9; // 获取基数,三位数对应100,四位数对应1000...
num += (n / count); // 加上偏移量获取对应的数字
char[] cs = String.valueOf(num).toCharArray(); // 对应的数字按位数拆分
return cs[n % count] - '0'; // 返回第 n%count 位的数字
}
}
注意点
- 判断条件n - num * count >= 0,这里是≥0,等于0代表是当前count位数的首个数字
- num要用long进行修饰,确保num与count进行相乘后不会因越界而导致计算出错