剑指 Offer 44. 数字序列中某一位的数字
解题思路
输入第n位首先找出第n位对应的数字位数,然后根据位数找到此位所对数值num,然后找到n所对num中的第几位数字.
1. 第一步确定所求数位的所在数字的位数
digit为1位的数共有10个(0-9),2位的共有90个(10-99),三位的共有900个(100-999)…然后每位所对位数的所有数字位数和count分别是:digit为1共有101位,digit为2共有902位,digit为3的共有900*3位…;则起始数值start分别是0,10,100…,位数digit开始数是1,2,3…;digit所对位数的数位数量count分别是10,180,2700…;
输入n,循环判断n位所在数字,
long start = 1;
int digit = 1;
long count = 10;
while(n > count) //当剩余的n大于下一个count时退出
{
n -= count;
start *= 10; //起始数值
digit += 1; //数值位数
count = 9*digit*start; //对应位所有数的总位数
}
2. 第二步确定所求数位所在的数字
第一步已近计算出所求位数对应的是几位数,根据对应位数计算对应数字.这里的第几位数字都是从0开始计算的,我们可以假设输入的是10,那么在这一步得到的是一个两位数,且是两位数开始的第0位.
即所求数位 在从数字 start 开始的第 [n / digit]个 数字 中( start为第 0 个数字)。num = start + n / digit.
3. 第三步确定所求数位在 num的哪一数位
通过求余即 n%digit得到所求数位是num中的哪一位.然后将num转换为字符串,返回n%digit位的字符对应的整数.
举例说明:输入1000
我们知道一位数有10个,两位数有90个,三位数有900个……。1000 - 10 - 90 * 2 = 810 < 900 * 3,故该数是一个三位数,且是三位数开始的第810位(这里的第810位是从0开始计算的,我们可以假设输入的是10,那么在这一步得到的是一个两位数,且是两位数开始的第位)。
[810/3]得到的就是从100开始的第几位数。因此该数为100 + 270= 370。
(810) % 3 = 0,可知该位是该数从左向右的第0位数即为3.
class Solution {
public:
int findNthDigit(int n) {
//第一步确定所求数位所在数字位数
long long start = 1,digit = 1;
long long count = 9;
while(n > count) //当剩余的n大于下一个count时退出
{
n -= count;
start *= 10; //起始数值
digit += 1; //数值位数
count = 9*digit*start; //对应位所有数的总位数
}
//第二步找到所求位数所在的数字
long long num = start + (n-1) / digit;
//第三部找到所求位数在num的哪一位
int res = (n-1) % digit;
string str = to_string(num);
return str[res]-'0';
}
};