题目大意
在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …中找到第 n 个数字。
注意:
n 是正数且在32位整数范围内 ( n < 231)。
示例:
输入:
11
输出:
0
说明:
第11个数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是0,它是10的一部分。
解题思路
我们首先计算位数为1的数字的总数字个数,即1~9共9个;
计算位数为2的数的总数字个数,即10~99,共90个数,按照题目要求,实际上是180个数字;
计算位数为3的数的总数字个数,即100~999,共900个数,按照题目要求,实际上是2700个数字;
…
给定n,先看看n是否落在位数为1的数中–>如果n<9,表示n落在位数为1的数中(1~9);
否则,n=n-9,看是否括在位数为2的数中–>如果n<180,表示n落在位数为2的数中(10~99);
以此类推,找到n落在位数为k的范围内(10k~10k+1-1);
当前位数为k,计算res=n%k和n=n/k。
若res=0:表示所求的结果是10k+(n-1)的数的最后一位;
若res!=0:表示结果是10k+n的数中,从前往后数第res位数字;
举例说明:
n=15。首先n>9–>n=n-9=6(这里表明n不会落在位数为1的范围内了);第二步,n<180(表示n落在了位数为2的范围内)。既然位数为2,表示一个数中含有两个数字,所以res=6%2=0,n=6/2=3。表示结果是位数为2的范围内的第三个数的最后一位,即12的最后一位,2;
class Solution {
public:
int findNthDigit(int n) {
int count = 1;
// 这里找到n落在位数为count的范围内;
while (n - 9 * pow(10, count - 1) * count >= 0){
n -= 9 * pow(10, count - 1) * count;
++count;
}
// 求余数和除数
int res = n % count;
n /= count;
// 找到位数为count范围内的第n个数(注意,n不是原来的n了)
int target_num = pow(10, count - 1) + n;
// 没有余数,表示是第n个数的最后一位
if (!res){
return target_num % 10;
}
// 有余数,找到n的下一个数字,从前往后第res位
// 为了省事,先转成字符串,然后直接到第res位了......
else{
return int(to_string(target_num)[res - 1] - '0');
}
}
};