Description:
Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …
Note:
- n is positive and will fit within the range of a 32-bit signed integer (n < 231).
Example 1:
Input:
3
Output:
3
Example 2:
Input:
11
Output:
0
Explanation:
The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
题意:从自然数序列中找出第N个数字,例如,要找出第11个数字,则为
1,2,3,4,5,6,7,8,9,1,0,1,1,1,2,1,3,1,4,…,
解法:最简单的办法自然就是从1开始,统计数字的个数直到数字个数为N位置,但是效率太低了,而且肯定会超时的。下面我们先计算一下数字长度为
l
(
l
≥
1
)
l(l \ge 1)
l(l≥1)的数量各为多少
l
=
1
:
c
o
u
n
t
[
1
,
9
]
=
9
=
9
×
1
×
1
0
1
−
1
l
=
2
:
c
o
u
n
t
[
10
,
99
]
=
180
=
9
×
2
×
1
0
2
−
1
l
=
3
:
c
o
u
n
t
[
100
,
999
]
=
2700
=
9
×
3
×
1
0
3
−
1
⋯
l
=
L
:
c
o
u
n
t
[
1
0
L
−
1
,
1
0
L
−
1
]
=
9
×
L
×
1
0
L
−
1
\begin{aligned} l &= 1:count_{[1,9]}=9=9\times1\times10^{1-1}\\ l &= 2:count_{[10,99]}=180=9\times2\times10^{2-1}\\ l &= 3:count_{[100,999]}=2700=9\times3\times10^{3-1}\\ &\cdots \\ l &= L:count_{[10^{L-1},10^{L}-1]}=9\times{L}\times10^{L-1} \end{aligned}
llll=1:count[1,9]=9=9×1×101−1=2:count[10,99]=180=9×2×102−1=3:count[100,999]=2700=9×3×103−1⋯=L:count[10L−1,10L−1]=9×L×10L−1
第一步:我们从长度
l
=
1
l=1
l=1开始统计数字的个数
c
o
u
n
t
count
count,直到数字的个数不小于
N
N
N,这个时候我们得到了第
N
N
N个数字所在的数字的长度为
l
e
n
len
len;
第二步:确认第
N
N
N个数字所在的那个自然数;利用
(1)
(
N
−
c
o
u
n
t
−
数
字
长
度
为
l
e
n
的
个
数
)
/
l
e
n
(N-count-数字长度为len的个数) / len \tag{1}
(N−count−数字长度为len的个数)/len(1)
得到第
N
N
N个数字所在自然数与长度为
l
e
n
len
len的最小自然数的距离,即可确定第
N
N
N个数字所在的自然数;
第三步:对于第二步中计算第
N
N
N个数字所在的自然数,我们需要考虑到两种情况
- 如果计算结果(1)中可以整除,那么就是所找的自然数的最后一位
- 如果计算结果(1)不可以整数且得到余数remainder,那么就是所找的自然数+1中距最高位的remainder位的那个数字
Java
class Solution {
public int findNthDigit(int n) {
long count = 0;
int len = 0;
while (count < n) {
len++;
count += 9 * len * Math.pow(10, len - 1);
}
if (len == 1) {
return n;
} //1~9
count -= 9 * len * Math.pow(10, len - 1);
int base = (int)Math.pow(10, len - 1);
long digit = base + (n - count) / len - 1;
long remainder = (n - count) % len;
if (remainder == 0) {
return (int)(digit % 10);
}
digit++;
return (int)(digit / (int)Math.pow(10, len - remainder)) % 10;
}
}