Given the infinite sequence formed by concatenating the non-negative integers: 0123456789101112131415... . The sequence is 0-indexed, i.e., the 0th digit is 0, the 1st digit is 1, the 2nd digit is 2, and so on.
Given an integer n, find the digit at the nth position in the sequence.
Examples:
Input: n = 12
Output: 1
Explanation: 1 is the 12th digit of the given sequence: 0123456789101112131415...Input: n = 19
Output: 4
Explanation: 4 is the 19th digit of the given sequence.
Table of Content
[Naive Approach] Generate Numbers One by One - O(n) Time and O(log n) Space
The idea is to generate numbers starting from 0 and count their digits one by one.
Working of Approach:
- Start generating numbers from 0.
- Convert each number into a string to count its digits.
- If n is smaller than the number of digits, the answer is inside that number.
- Otherwise, subtract the number of digits from n and continue.
- Return the required digit when its position is found.
#include <iostream>
using namespace std;
int nthDigit(int n)
{
// Start from number 0
int num = 0;
while (true)
{
// Convert number to string
string s = to_string(num);
// If nth digit is inside this number
if (n < s.size())
return s[n] - '0';
// Skip all digits of current number
n -= s.size();
// Move to next number
num++;
}
}
int main()
{
int n = 19;
cout << nthDigit(n);
return 0;
}
import java.util.*;
public class GFG {
public static int nthDigit(int n)
{
// Start from number 0
int num = 0;
while (true) {
// Convert number to string
String s = Integer.toString(num);
// If nth digit is inside this number
if (n < s.length())
return s.charAt(n) - '0';
// Skip all digits of current number
n -= s.length();
// Move to next number
num++;
}
}
public static void main(String[] args)
{
int n = 19;
System.out.println(nthDigit(n));
}
}
def nthDigit(n):
# Start from number 0
num = 0
while True:
# Convert number to string
s = str(num)
# If nth digit is inside this number
if n < len(s):
return int(s[n])
# Skip all digits of current number
n -= len(s)
# Move to next number
num += 1
if __name__ == "__main__":
n = 19
print(nthDigit(n))
using System;
public class GFG {
public static int nthDigit(int n)
{
// Start from number 0
int num = 0;
while (true) {
// Convert number to string
string s = num.ToString();
// If nth digit is inside this number
if (n < s.Length)
return s[n] - '0';
// Skip all digits of current number
n -= s.Length;
// Move to next number
num++;
}
}
public static void Main()
{
int n = 19;
Console.WriteLine(nthDigit(n));
}
}
function nthDigit(n)
{
// Start from number 0
let num = 0;
while (true) {
// Convert number to string
let s = num.toString();
// If nth digit is inside this number
if (n < s.length)
return parseInt(s[n]);
// Skip all digits of current number
n -= s.length;
// Move to next number
num++;
}
}
// Driver Code
let n = 19;
console.log(nthDigit(n));
Output
4
[Expected Approach] Using Digit-Length Blocks - O(log n) Time and O(1) Space
The idea is to handle 0 separately and divide the remaining numbers into blocks based on their number of digits, such as 1-9, 10-99, 100-999, and so on.
Working of Approach:
- Start with the 1-digit block containing numbers 1 to 9.
- Calculate the total digits in the current block as digits * count.
- Skip the block if n is greater than its total digits.
- Find the actual number using (n - 1) / digits.
- Find the digit position using (n - 1) % digits.
Let us understand with an example:
Input: n = 19
- Initially, digits = 1, count = 9, start = 1, and k = 19. Since 19 > 1 × 9, skip the 1-digit block: k = 10, digits = 2, count = 90, start = 10.
- Now k = 10 is not greater than 2 × 90, so the required digit lies in the 2-digit block (10 to 99).
- Find the number: start = 10 + (10 - 1) / 2 = 14.
- Find the digit position: pos = (10 - 1) % 2 = 1.
- 14[1] = 4, so the answer is 4.
#include <iostream>
using namespace std;
int nthDigit(int n)
{
// number of digits in current block
int digits = 1;
// numbers in this block
int count = 9;
int start = 1;
// safe working variable
int k = n;
// step 1: find correct digit-length block
while (k > digits * count)
{
k -= digits * count;
digits++;
count *= 10;
start *= 10;
}
// step 2: find actual number
start += (k - 1) / digits;
// step 3: find digit index inside number
int pos = (k - 1) % digits;
// convert and extract digit
string s = to_string(start);
return s[pos] - '0';
}
int main()
{
int n = 19;
cout << nthDigit(n);
return 0;
}
import java.util.*;
public class GFG {
public static int nthDigit(int n)
{
// number of digits in current block
int digits = 1;
// numbers in this block
int count = 9;
int start = 1;
// safe working variable
int k = n;
// step 1: find correct digit-length block
while (k > digits * count) {
k -= digits * count;
digits++;
count *= 10;
start *= 10;
}
// step 2: find actual number
start += (k - 1) / digits;
// step 3: find digit index inside number
int pos = (k - 1) % digits;
// convert and extract digit
String s = Integer.toString(start);
return Character.getNumericValue(s.charAt(pos));
}
public static void main(String[] args)
{
int n = 19;
System.out.println(nthDigit(n));
}
}
def nthDigit(n):
# number of digits in current block
digits = 1
# numbers in this block
count = 9
start = 1
# safe working variable
k = n
# step 1: find correct digit-length block
while k > digits * count:
k -= digits * count
digits += 1
count *= 10
start *= 10
# step 2: find actual number
start += (k - 1) // digits
# step 3: find digit index inside number
pos = (k - 1) % digits
# convert and extract digit
s = str(start)
return int(s[pos])
if __name__ == '__main__':
n = 19
print(nthDigit(n))
using System;
public class GFG {
public static int nthDigit(int n)
{
// number of digits in current block
int digits = 1;
// numbers in this block
int count = 9;
int start = 1;
// safe working variable
int k = n;
// step 1: find correct digit-length block
while (k > digits * count) {
k -= digits * count;
digits++;
count *= 10;
start *= 10;
}
// step 2: find actual number
start += (k - 1) / digits;
// step 3: find digit index inside number
int pos = (k - 1) % digits;
// convert and extract digit
string s = start.ToString();
return int.Parse(s[pos].ToString());
}
public static void Main()
{
int n = 19;
Console.WriteLine(nthDigit(n));
}
}
function nthDigit(n)
{
// number of digits in current block
let digits = 1;
// numbers in this block
let count = 9;
let start = 1;
// safe working variable
let k = n;
// step 1: find correct digit-length block
while (k > digits * count) {
k -= digits * count;
digits++;
count *= 10;
start *= 10;
}
// step 2: find actual number
start += Math.floor((k - 1) / digits);
// step 3: find digit index inside number
let pos = (k - 1) % digits;
// convert and extract digit
let s = start.toString();
return parseInt(s[pos]);
}
// Driver Code
let n = 19;
console.log(nthDigit(n));
Output
4