文章目录
题目描述
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
示例 1:
输入:n = 3
输出:3
示例 2:
输入:n = 11
输出:0
题解思路
这道题其实就是找一下规律,同时需要我们细心计算好一些细节,比如位数、余数、索引等。
- 找到 n 属于哪个数位里的索引。比如 n = 5,那 n 就是个位这个数位里的索引;或者 n = 11,那 n 就是十位这个数位里的索引。
- 确定了 n 属于哪个数位,我们需要进一步定位到 n 具体属于哪个数。比如 n = 11,指的就是 10 这个数。
- 确定了 n 属于哪个数,我们就需要算出 n 是这个数的第几位,从而得到最终答案。比如 n = 11,指的是 10 这个数的第 1 位(索引从 0 开始),从而最终答案就是 0。
这里我们定义了几个变量来帮助我们完成上面的三步(代码中对应处也有注释):
- digit。表示数位,比如个位,digit = 1;十位,digit = 2;百位,digit = 3;以此类推。
- start。表示该数位的所有数的起始点数。比如个位,start = 1(0 做特例处理,不算在内);十位,start = 10;千位,start = 1000;以此类推。
- index_count。表示该数位一共有的索引个数。比如个位,index_count = 9(1-9);十位,index_count = 180(10-99);百位,index_count = 2700(100-999);以此类推。我们可以总结出这么一条规律:index_count = digit * 9 * start。比如十位,index_count = 2 * 9 * 10 = 180。
代码实现:
class Solution {
public:
int findNthDigit(int n) {
if(n < 0) return -1;
if(n == 0) return 0;
int digit = 1; // 数位(各位/十位/百位... 对应 1/2/3...)
long start = 1; // 属于该数位的所有数的起点数(个位是1,十位是10,百位是100)
long index_count = digit * 9 * start; // 该数位的数一共的索引个数
while(n > index_count){
// 找出 n 属于哪个数位里的索引
n -= index_count;
++digit;
start *= 10;
index_count = digit * 9 * start;
}
// 上面的循坏结束后
// digit 等于原始的 n 所属的数位;start 等于原始 n 所属数位的数的起点
// index_count 等于原始的 n 所属数位的索引总个数(不重要了,下面不用)
// n 等于在当前数位里的第 n-1 个索引(索引从 0 算起)
long num = start + (n-1)/digit; // 得到原始的 n 对应哪个数字
int remainder = (n-1) % digit; // 余数就是原始的 n 是这个数字中的第几位
string s_num = to_string(num);
return int(s_num[remainder] - '0'); // n 对应着第 remainder 位,再转成 int
}
};
如有帮助到您,可以多多点赞、评论鼓励哟~~~