Given an integer d
between 0
and 9
, and two positive integers low
and high
as lower and upper bounds, respectively. Return the number of times that d
occurs as a digit in all integers between low
and high
, inclusive.
Example 1:
Input: d = 1, low = 1, high = 13 Output: 6 Explanation: The digit d=1 occurs 6 times in 1, 10, 11, 12, 13.
Example 2:
Input: d = 3, low = 100, high = 250 Output: 35 Explanation: The digit d=3 occurs 35 times in 103, 113, 123, 130, 131, ..., 238, 239, 243.
Constraints:
0 <= d <= 9
1 <= low <= high <= 2 * 108
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to counting digits in a range involves examining every number within the given range. For each number, we'll inspect its digits and count how many times our target digit appears. This is a straightforward but potentially slow method.
Here's how the algorithm would work step-by-step:
def digit_count_in_range_brute_force(low_number, high_number, target_digit):
digit_count = 0
# Iterate through all numbers in the specified range
for current_number in range(low_number, high_number + 1):
number_string = str(current_number)
# Iterate through the digits of the current number
for digit_char in number_string:
digit = int(digit_char)
# Check if the digit matches the target digit
if digit == target_digit:
# Increment the digit count if it matches
digit_count += 1
return digit_count
The efficient strategy is to count the occurrences of a digit within a range by cleverly breaking the range down digit by digit. We avoid checking every single number within the range directly. This approach cleverly uses math to avoid brute force.
Here's how the algorithm would work step-by-step:
def digit_count_in_range(
lower_bound,
upper_bound,
digit_to_count):
def count_digit_up_to_number(
number,
digit_to_count):
string_number = str(number)
number_length = len(string_number)
count = 0
for i in range(number_length):
current_digit = int(string_number[i])
power_of_ten = 10 ** (number_length - i - 1)
# Calculate count when current digit is less than digit to count.
if current_digit < digit_to_count:
count += int(string_number[:i] or 0) * power_of_ten
# Calculate count when current digit is greater than digit to count.
elif current_digit > digit_to_count:
count += (int(string_number[:i] or 0) + 1) * power_of_ten
# When equal, add the remaining digits + 1.
else:
count += int(string_number[:i] or 0) * power_of_ten + \
int(string_number[i+1:] or 0) + 1
#Exclude leading zeros if counting zeros.
if digit_to_count == 0 and i == 0:
count -= power_of_ten
return count
# Edge case: if lower bound is 0, avoid double counting.
count_at_lower_bound = count_digit_up_to_number(
lower_bound - 1,
digit_to_count
) if lower_bound > 0 else 0
count_at_upper_bound = count_digit_up_to_number(
upper_bound,
digit_to_count
)
# Subtract counts to get the count within the range.
return count_at_upper_bound - count_at_lower_bound
Case | How to Handle |
---|---|
low and high are equal and digit appears in that number | Handle this case by checking if the digit exists in the single number and returning 1 or 0. |
low is greater than high | Return 0 since there is no range. |
digit is outside the range [0, 9] | Treat as invalid input and return 0 (or throw an error). |
low and/or high are negative numbers | If negative numbers are not allowed, return 0 (or throw an error); otherwise handle correctly based on the intended behavior for negative ranges, considering the negative sign's impact on digit counts. |
low is 0 and high is a very large number (e.g., Integer.MAX_VALUE) | Consider the computational cost and potential for optimization to avoid timeout due to the large iteration range. |
digit is 0 and the range includes 0 | Handle this case carefully since many numbers in the range will contain the digit 0. |
low and high contain many occurrences of the digit | Ensure the algorithm correctly counts all occurrences without duplicates or omissions, especially when digits repeat within numbers. |
Integer overflow in calculations | Use long data types or other methods to prevent overflow when calculating digit counts, especially with very large ranges. |