You are given two integers, low
and high
, and a digit d
, which is an integer in the range [0, 9]
. Your task is to count the number of times the digit d
appears in all integers between low
and high
(inclusive).
Example 1:
d = 1, low = 1, high = 13
1
appears in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
. The digit 1
appears once in 1
, once in 10
, twice in 11
, once in 12
and once in 13
. So the total count is 1 + 1 + 2 + 1 + 1 = 6
.Example 2:
d = 0, low = 0, high = 10
0
appears in 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
. The digit 0
appears once in 0
, and once in 10
. So the total count is 1 + 1 = 2
.Example 3:
d = 2, low = 20, high = 25
2
appears in 20, 21, 22, 23, 24, 25
. The digit 2
appears once in 20
, once in 21
, twice in 22
, once in 23
, once in 24
, and zero times in 25
. So the total count is 1 + 1 + 2 + 1 + 1 + 0 = 6
.Write a function that takes three integers, d
, low
, and high
, as input and returns the number of times the digit d
appears in the range [low, high]
. Can you provide an efficient solution, considering potentially large ranges for low
and high
?
The most straightforward approach is to iterate through all numbers in the given range [low, high]
and, for each number, count the occurrences of the specified digit d
. This involves converting each number to a string and then iterating through the string to check each digit.
def digitsInNumber(num, digit):
count = 0
s = str(num)
for char in s:
if char == str(digit):
count += 1
return count
def digitsCountNaive(d, low, high):
count = 0
for i in range(low, high + 1):
count += digitsInNumber(i, d)
return count
high - low + 1
is the number of integers in the range, and log(high) is the average number of digits in each number. Converting each number to a string takes O(log(high)) time.A more efficient approach involves analyzing the digits of the numbers in the range directly. We can iterate through each digit position and calculate how many times the digit d
appears at that position within the range [1, n]
. By calculating the count for [1, high]
and subtracting the count for [1, low - 1]
, we obtain the count for the desired range [low, high]
. This prevents us from iterating through all the numbers in the range. Also, we must take into account leading zeroes.
countDigit(n, d)
that calculates the number of times digit d
appears in the numbers from 1 to n.n
to a string so we can iterate through the digits from left to right.n
.i
, calculate:
prefix
: The number formed by the digits to the left of position i
.currentDigit
: The digit at position i
.suffix
: The number formed by the digits to the right of position i
.currentDigit
compared to d
, update the count:
currentDigit < d
: The digit d
appears prefix * 10^(number of digits in suffix)
times.currentDigit == d
: The digit d
appears prefix * 10^(number of digits in suffix) + suffix + 1
times.currentDigit > d
: The digit d
appears (prefix + 1) * 10^(number of digits in suffix)
times.d == 0
to avoid counting leading zeros.countDigit(high, d) - countDigit(low - 1, d)
.def countDigit(n, d):
s = str(n)
length = len(s)
count = 0
for i in range(length):
prefix = 0 if i == 0 else int(s[:i])
currentDigit = int(s[i])
suffix = 0 if i == length - 1 else int(s[i+1:])
powerOf10 = 10 ** (length - i - 1)
if d == 0:
if i == 0:
continue # leading zeroes
if currentDigit > d:
count += prefix * powerOf10
elif currentDigit == d:
count += prefix * powerOf10 + suffix + 1
else:
count += (prefix - 1) * powerOf10
else:
if currentDigit > d:
count += (prefix + 1) * powerOf10
elif currentDigit == d:
count += prefix * powerOf10 + suffix + 1
else:
count += prefix * powerOf10
return count
def digitsCount(d, low, high):
return countDigit(high, d) - countDigit(low - 1, d)
high
and low
separately. Thus, the complexity is proportional to the number of digits in the input numbers.d
is 0 to avoid counting leading zeros.