描述
数字以 0123456789101112131415... 的格式作为一个字符序列,在这个序列中第 2 位(从下标 0 开始计算)是 2 ,第 10 位是 1 ,第 13 位是 1 ,以此类题,请你输出第 n 位对应的数字。
数据范围: 0≤n≤10^9
示例
// 输入
0
// 输出
0
// 输入
2
// 输出
2
// 输入
10
// 输出
1
// 输入
13
// 输出
1
解题思路
// 区间规律
0
1 ~ 9:1 * 9 = 9
10 ~ 99:2 * 90 = 180
100 ~ 999:3 * 900 = 2700
...
// n 属于哪个自然数
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
n - 区间首位 - 位数 - 所属自然数 - 下标
2 - 1 - 1 - 2=1+(2-1)/1 - 0=(2-1)%1
10 - 10 - 2 - 10=10+(10-9-1)/2 - 0=(10-9-1)%2
13 - 10 - 2 - 11=10+(13-9-1)/2 - 1=(13-9-1)%2
所属自然数 = 区间首位数 + 剩余部分除以这个区间的位数
从以上示例可以发现 n-1 和区间之间的规律
位数:digit
区间首位:start
区间总位数:sum = digit * 9 * start
区间剩余部分:x
所属自然数:start + (x-1)/digit
确定 n 属于哪个区间
- 通过 n 不断减去前面区间的位数
确定 n 属于哪个自然数
- 区间首位数 + 剩余部分 / 这个区间的位数
确定 n 在自然数中的位置
- n - 1 对这个位数取模
代码实现
/**
* [JZ44-简单] 数字序列中某一位的数字
*
* @param data int 整型一维数组
* @param k int 整型
* @return int 整型
*/
func findNthDigit(n int) int {
// 位数、区间首位数字、区间总位数
digit, start, sum := 1, 1, 9
// 获取位数、区间首位、区间总位数
for n > sum {
n -= sum
start *= 10
digit += 1
sum = 9 * start * digit
}
// 定位 n 在哪个数上
num := start + (n-1)/digit
// 定位 n 在这个数的哪一位上
index := (n - 1) % digit
// 将 num 转化成 string
numStr := strconv.Itoa(num)
// 根据 index 索引获取字符串值
numStr = string(numStr[index])
// 将字符串转化成 int
ret, _ := strconv.Atoi(numStr)
return ret
}
还不快抢沙发