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.
从整数序列 1,2,3,4,5,… 中查找第n个数字,n是正整数,且取值范围为[1,231)。
分析:
一个简单的思路是依次从序列中取出一个元素,将其转化为字符串,保存到字符串str中,不断循环,直到字符串的长度大于或等于n,取出第n个字符,转化为整数即可。
代码如下:
int findNthDigit(int n)
{
string str;
int cnt = 1;
while ((int)str.size() < n)
str += to_string(cnt++);
return str.at(n - 1) - '0';
}
这种方法虽然理论上可行,但是当n很大时,这个字符串将非常长,且字符串拼接过程相当漫长,代码效率过于低下,需另求思路。
我们知道,一位数有1~9共9个,两位数有10~99共90个,三位数有100~999共900个…因此对于n,我们可以很容易确定它在几位数范围内,进一步确定是哪个数,并确定是哪个数的哪一位数字。
具体做法是:定义一个变量k,用来记录当前的位数,另定义一个变量coef,用来记录k位数共有多少个数。当n大于k*coef(即多于所有k位数的数字总数)时,说明n不是k位数,而且其位数比k大,因此,减去k位数包含的总数字数,再与k+1位数比较。如此循环,直到n<=i*coef时,说明第n个数字在i位数范围内。具体值为i位数的最小值(即10i-1),加上第(n-1)/i个数,设此值为val,则val=10i-1+(n-1)/k。具体数字为(n-1)%i。
代码如下:
int findNthDigit(int n)
{
long long coef = 9;
int k = 1;
while (n > coef*k)
{
n -= coef*k;
coef *= 10;
k++;
}
long long val = pow(10, k - 1) + (n - 1) / k;
string str = to_string(val);
return str[(n - 1) % k] - '0';
}
浙公网安备 33010602011771号