Given two integers left and right, return the count of numbers in the inclusive range [left, right] having all digits unique.
Example 1:
Input: left = 1, right = 20
Output: 19
Explanation: All numbers from 1 to 20 have unique digits.
Example 2:
Input: left = 100, right = 110
Output: 10
Explanation: The numbers in the range [100, 110] with unique digits are: 102, 103, 104, 105, 106, 107, 108, 109, 110 (skipping 100 and 101 as they have duplicate digits).
The count is 10.
Constraints:
1 <= left <= right <= 108When 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:
To find the numbers with unique digits within a given range using a brute force approach, we essentially check every single number within that range. For each number, we then verify if all of its digits are different from each other.
Here's how the algorithm would work step-by-step:
def count_numbers_with_unique_digits_brute_force(start_range, end_range):
count_unique_digits = 0
for number in range(start_range, end_range + 1):
number_string = str(number)
digits_seen = set()
is_unique = True
# Check each digit of current number
for digit_character in number_string:
digit = int(digit_character)
# If digit is already seen, not unique
if digit in digits_seen:
is_unique = False
break
digits_seen.add(digit)
# Increment count if the digits were all unique
if is_unique:
count_unique_digits += 1
return count_unique_digitsThe problem is about counting numbers with unique digits within a specified range. The efficient approach avoids generating and checking every single number by using combinatorics and dynamic programming to calculate the count directly.
Here's how the algorithm would work step-by-step:
def count_numbers_with_unique_digits_ii(low_range, high_range):
if low_range > high_range:
return 0
count = 0
# Single digit numbers always have unique digits
if low_range <= 0 <= high_range:
count += 1
for number_length in range(1, 11):
if number_length == 1:
unique_digit_count = 9
else:
unique_digit_count = 9
available_digits = 9
# Calculate the count for the current length
for _ in range(number_length - 1):
unique_digit_count *= available_digits
available_digits -= 1
lower_bound = 10 ** (number_length - 1)
upper_bound = (10 ** number_length) - 1
# Numbers of this length are within the range
if lower_bound >= low_range and upper_bound <= high_range:
count += unique_digit_count
# Adjust for low_range bound
elif lower_bound < low_range <= upper_bound:
count += count_valid_numbers_in_range(low_range, upper_bound, number_length)
# Adjust for high_range bound
elif lower_bound <= high_range < upper_bound:
count += count_valid_numbers_in_range(lower_bound, high_range, number_length)
# The range lies entirely within this length
elif low_range < lower_bound and high_range > upper_bound:
count += unique_digit_count
return count
def count_valid_numbers_in_range(lower_bound, upper_bound, number_length):
count = 0
for number in range(lower_bound, upper_bound + 1):
if has_unique_digits(number):
count += 1
return count
def has_unique_digits(number):
digits = set()
for digit in str(number):
if digit in digits:
return False
digits.add(digit)
return True| Case | How to Handle |
|---|---|
| n = 0 | Return 1 since a number with 0 digits (empty number) is considered to have unique digits. |
| n = 1 | Return 10 because the unique numbers are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. |
| n > 10 | Return the same result as n = 10 because a number with more than 10 digits cannot have all unique digits. |
| Integer overflow for large n during calculation | Ensure the data type used for intermediate calculations and final result is large enough (e.g., long) to prevent integer overflow. |
| All possible digits are used up at some i < n | The loop should terminate when the number of unique digits reaches the maximum possible. |
| Negative input for n | Throw an IllegalArgumentException or return 0 since negative input is not a valid number of digits. |
| Edge case where n is close to overflow range | Handle intermediate results and ensure that they do not overflow, likely requiring `long` rather than `int`. |
| Empty digit sequences | Count the empty sequence as the case when n=0, thus returning 1. |