题目
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
剑指offer44
思路+代码详解
核心思路就是按照数字的位数进行分组,注意边界处理,根据分组查找第n位对应的数字
class Solution {
public:
int findNthDigit(int n) {
//0-9都是个位数
//10-99都是2位数,第10位数字为"1",是第一个2位数的第一个数
//100-999都是3位数,第190位数字为"1",是第一个3位数的第一个数(190=10+9*10*2)
//1000-9999都是4位数,第2890位数字为"1",是第一个4位数的第一个数(2890=190+9*10^2*3)
//10000-99999都是5位数,第38890位数字为"1",是第一个5位数的第一个数(38890=2890+9*10^3*4)
if(n<10)return n;//10位以内的数字直接返回
vector<int> group;//分组,group[i]表示i+2位数序列的第一个数的序列位数
long len=10;
group.push_back(len);//将10存入group[0]中,表示第10位是2位数序列的第一个数,,
int i=0;
while(len<=n){
i++;
len+=9*pow(10,i)*(i+1);//每一位数的第一个数的位置作为分界线
group.push_back(len);
}//循环结束时,i指向大于n位的下一个分界线,因此i-1是n所处的分组位置
int g=group[i-1];
int first=pow(10,i);//first是当前n所处的分组位置的第一个数
n-=g;//在i+1位数圈子里的第n位
int pern_len=i+1;//该分组是pern_len位数
int b=n/pern_len;//圈子里的第几个数
int a=n%pern_len;//圈子里第b个数的第a位(从左往右数)
int res=first+b;//n所处的数字
string ans=to_string(res);
return ans[a]-'0';//n所处的位置数字
}
};