找出无限正整数数列1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …中的第n个数位。
n是一个正整数,并且不会超出32位有符号整数的范围(n < 2^31)。
样例
样例 1:
输入:3
输出:3
样例 2:
输入:11
输出:0
解析:数字序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 第11位是0
题目的意思是有一个以正整数(1,2,3,4,依次向后加1)为基础组成的序列(也可以理解为字符串),传入一个整数n,找出在该序列中的第n位数字。该序列含有以下规律:
1-9,有9个一位数,当n小于等于9的时候,可以在里面找到值。
10-99,有90个两位数,当n大于9且小于等于180+9=189时,可以在里面找到值。
100-999,有900个三位数,当n大于189且小于900x3+189=2889时,可以在里面找到值。
我们可以将此问题分解为三个步骤:
先计算该数字的位数,确定范围。
找出该数字。
确定是该数字中的第几位数。
例如:303
第一步,因为189<303<2889,所以我们要找的是一个三位数,303-189=114,此时n变成114。
第二步,我们要找的数变成了三位数中的第114位,那我们就可以计算出三位数中的第114位数是100+(114-1)/3=137。这里减1是因为在字符串中,索引是从0开始的,而我们的序列字符串是从1开始,所以要减1,你也可以从一开始就减1。
第三步,计算是137中的第几位数,(114-1)%3=2,也就是137的第2位(从0开始)数7,就是我们想要的结果。
在代码中我们使用long类型,预防溢出的风险。
class Solution {
public:
/**
* @param n: a positive integer
* @return: the nth digit of the infinite integer sequence
*/
int findNthDigit(int n) {
// write your code here
long count=1;//
int start=1;//数字长度即几位数
int num=1;
while(n>9*count*start)
{
n-=9*count*start;
count*=10;
start++;
}
count+=(n-1)/start;
int cur=(n-1)%start;
string result=to_string(count);
return result[cur]-'0';
}
};