题目来源 ====》》 【力扣第400题. 第 N 位数字】
题目描述
给你一个整数 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 的一部分。
提示:
1 <= n <= 231 - 1
解题思路
分析题意,这是一个找规律的细节题。
对题目的规律分析:
- 1位数为1~9,含有9个数字;
- 2位数为10~99,含有 90 *2 个数字
- …
- k位数为10k-1~10k-1,含有9 k 10k-1
得到上面的规律后,我们可以想到以下解题步骤:
- 先找出第n位数字所在数为几位数,用k表示;
- 知道第n位数字所在数为k位数后,可以在找出第n位数字在k位数中是第几位,这个可以做减法循环可以求得,仍用n表示;
- k位数的第n位,可以得到具体数字*num,*即10k-1+(n-1)/k;
- 求具体位num的第几位,即**(n-1)%k**;
- 将num转位字符串即可直接得到num的第 (n-1)%k 位数字是什么
代码
class Solution {
public:
int findNthDigit(int n) {
long k = 1,start_num = 1,count = 9;
//k用来存放第n位所在数字的位数,即k位数
//start_num确定所求的数是几位数的初始值1,10,100,···
//count表示k位数中含有数字的个数。即9,90*2,900*3,···
while(n > count){
n -= count;
start_num *= 10;
k += 1; //1,2,3
count = 9 * start_num * k;
}
//循环结束后n为k位数的第n位
//并且确定了start_num,k和count
//num为第n位所在数字
long num = start_num + (n-1)/k; //(n-1)/k是表示的是第n位所在数字在k位数中的第几位
int res = int(to_string(num)[(n-1) % k] - '0'); //(n-1) % k是求所求具体数字是num的第几位数
return res;
}
};