题目链接
顺序归纳法
1. 确定该数字有多少位
- 1 1 1 位的数字 0 0 0 ~ 9 9 9 共有 10 10 10 位
- 2 2 2 位的数字共有 10 10 10 ~ 99 99 99 共有 90 90 90 * 2 2 2 = 180 180 180 位
- 3 3 3 位的数字共有 100 100 100 ~ 999 999 999 共 900 900 900 * 3 3 3 = 2700 2700 2700 位
- …
故我们可得:
- 1 1 1 位的数字共有 10 10 10 位
- k k k 位的数字共有 9 9 9 * 1 0 k − 1 10^{k-1} 10k−1 * k k k 位, k > 1 k>1 k>1
2. 确定这一位所在数字
现在我们已经知道了数字的位数,那么对于 n n n 位的数字,每隔 n n n 位就是一个 n n n 位数,据此我们就可以得到具体的数字
3. 确定这一位
很简单,具体看代码
代码
注意乘法溢出问题
class Solution {
public:
int digitAtIndex(int n) {
int len = 1; // 数字位数
long long base = 9, limit = 10; // 注意溢出问题
// 1. 得到数字的位数
while(n > limit) {
len ++ ;
base *= 10;
limit += base * len;
}
// 2. 得到具体的数字
// n 减去 1~n-1 位所有数字的位数之和,就可以得到 n 位数字的总位数: m = n - (limit - base * len)
// m / len 即可得到第 n 位所在数字是第几个 n 位数: num = m / len
int m = n - (limit - base * len);
int num = m / len + pow(10, len - 1);
// 3. 计算具体的是数字 num 的哪一位
// 之前我们已经计算出了 n 位数字的总位数 m 和 数字 num
// 现在用 m - (num - pow(10, len-1)) * len 即可得到该数字是 num 的哪一位
int idx = m - (num - pow(10, len - 1)) * len;
return to_string(num)[idx] - '0';
}
};