(C++)剑指offer-拓展:数字序列中某一位的数字
分析数字规律可以发现,个位数有9个(不包括0),2位数有90个(10 - 99),3位数有900个(100 - 999),依次类推;因此处理步骤主要为三个过程:
1.定位第n个数字所在的数属于i位数的区域;
2.定位第n个数字所在对应i位数区域中的哪一个i位数;
3.定位第n个数字在那个i位数中的第几位。
通过上述规律筛出,问题整体的时间复杂度为O(logn)。具体代码如下:
class Solution {
public:
int digitAtIndex(int n) {
long long i = 1, s = 9, base = 1; //i位数:如23,i=2;s对应数量:如i=2的两位数有90个,10至99;base该位数的第一个数如两位数的第一个数是10
while(n > i * s){ //opps
n -= i * s;
i++;
s *= 10;
base *= 10;
}
int num = base + (n + i - 1) / i - 1; //步骤2.求解对应i位数中的哪一个,(n + i - 1) / i表示 n / i向上取整,如8 / 3 = 3,最后减1是因为i = 1时,没包括0,但是序列是从0开始的因此左移一位消除
int r = n % i ? n % i : i; //确定是步骤2.中数字的哪一位
for(int j = 0; j < i - r; j++){ //如1243第3位,左移4 - 3 = 1位再取余即为所求
num /= 10;
}
return num % 10;
}
};