Given an integer n
, return the nth
digit of the infinite integer sequence [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
.
Example 1:
Input: n = 3 Output: 3
Example 2:
Input: n = 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.
Constraints:
1 <= n <= 231 - 1
This problem asks to find the nth digit in the infinite sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... A naive approach of iterating through the sequence until the nth digit is found would be highly inefficient. Instead, we use a mathematical approach to solve this efficiently.
Mathematical Approach
The core idea is to determine the length of the numbers (number of digits) that contain the nth digit. We can then identify the specific number and digit within that number.
Grouping by Digit Length: The sequence can be divided into groups based on the number of digits.
Finding the Relevant Group: We iteratively check which group contains the nth digit. We start with 1-digit numbers, then 2-digit, 3-digit, and so on. We keep track of the cumulative number of digits (cnt
) across groups. As soon as the cumulative count (cnt
) exceeds or equals n
, we've found the group containing the nth digit.
Identifying the Number and Digit:
num
) containing the nth digit.idx
) of the digit within that number.Time Complexity Analysis:
The loop iterating through the digit lengths (1, 2, 3, ...) runs at most log₁₀(n) times. This is because the number of digits in the number containing the nth digit is roughly proportional to log₁₀(n). All other operations within the loop are constant time. Therefore, the overall time complexity is O(log₁₀(n)), which is very efficient.
Space Complexity Analysis:
The space complexity is O(1) because we use only a constant number of variables to store intermediate values.
Code Examples
The following code examples demonstrate the solution in various programming languages. They all follow the same mathematical approach explained above.
Python
class Solution:
def findNthDigit(self, n: int) -> int:
k, cnt = 1, 9
while k * cnt < n:
n -= k * cnt
k += 1
cnt *= 10
num = 10 ** (k - 1) + (n - 1) // k
idx = (n - 1) % k
return int(str(num)[idx])
Java
class Solution {
public int findNthDigit(int n) {
int k = 1, cnt = 9;
while ((long) k * cnt < n) {
n -= k * cnt;
++k;
cnt *= 10;
}
int num = (int) Math.pow(10, k - 1) + (n - 1) / k;
int idx = (n - 1) % k;
return String.valueOf(num).charAt(idx) - '0';
}
}
C++
class Solution {
public:
int findNthDigit(int n) {
long long k = 1, cnt = 9;
while (k * cnt < n) {
n -= k * cnt;
++k;
cnt *= 10;
}
long long num = pow(10, k - 1) + (n - 1) / k;
int idx = (n - 1) % k;
return to_string(num)[idx] - '0';
}
};
Go
func findNthDigit(n int) int {
k, cnt := 1, 9
for (k * cnt) < n {
n -= (k * cnt)
k++
cnt *= 10
}
num := int(math.Pow10(k-1)) + (n-1)/k
idx := (n - 1) % k
return int(strconv.Itoa(num)[idx] - '0')
}
JavaScript
var findNthDigit = function(n) {
let k = 1, cnt = 9;
while (k * cnt < n) {
n -= k * cnt;
k++;
cnt *= 10;
}
let num = Math.pow(10, k - 1) + Math.floor((n - 1) / k);
let idx = (n - 1) % k;
return parseInt(String(num)[idx]);
};
C#
public class Solution {
public int FindNthDigit(int n) {
long k = 1, cnt = 9;
while (k * cnt < n) {
n -= (int)(k * cnt);
k++;
cnt *= 10;
}
long num = (long)Math.Pow(10, k - 1) + (n - 1) / k;
int idx = (n - 1) % (int)k;
return int.Parse(num.ToString()[idx].ToString());
}
}
These code examples efficiently solve the problem by leveraging the mathematical properties of the digit sequence, achieving a logarithmic time complexity. Note that type handling (e.g., long long
in C++) might be necessary to prevent integer overflow for large values of n
.