A digit string is good if the digits (0-indexed) at even indices are even and the digits at odd indices are prime (2, 3, 5, or 7).
"2582" is good because the digits (2 and 8) at even positions are even and the digits (5 and 2) at odd positions are prime. However, "3245" is not good because 3 is at an even index but is not even.Given an integer n, return the total number of good digit strings of length n. Since the answer may be large, return it modulo 109 + 7.
A digit string is a string consisting of digits 0 through 9 that may contain leading zeros.
Example 1:
Input: n = 1 Output: 5 Explanation: The good numbers of length 1 are "0", "2", "4", "6", "8".
Example 2:
Input: n = 4 Output: 400
Example 3:
Input: n = 50 Output: 564908303
Constraints:
1 <= n <= 1015When 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 good numbers involves checking every single possible number with a specific number of digits to see if it meets the criteria. We systematically generate each candidate number and test it. This is guaranteed to find the answer, but it may take a long time.
Here's how the algorithm would work step-by-step:
def count_good_numbers_brute_force(number_of_digits):
start_number = 10 ** (number_of_digits - 1)
end_number = (10 ** number_of_digits) - 1
good_numbers_count = 0
# Iterate through every number within specified digit range.
for current_number in range(start_number, end_number + 1):
is_good = True
number_as_string = str(current_number)
#Check the 'good' criteria (even positions even, odd positions odd).
for index, digit in enumerate(number_as_string):
digit_value = int(digit)
if index % 2 == 0 and digit_value % 2 != 0:
is_good = False
break
if index % 2 != 0 and digit_value % 2 == 0:
is_good = False
break
# Increment the count if the number meets 'good' criteria
if is_good:
good_numbers_count += 1
return good_numbers_countInstead of checking every possible number, the optimal approach uses math and a divide-and-conquer strategy to count the 'good' numbers quickly. We can break down the problem into smaller, easier-to-solve pieces and then combine the results efficiently.
Here's how the algorithm would work step-by-step:
def count_good_numbers(number): modulo = 10**9 + 7
def fast_power(base, power): result = 1
while power > 0:
if power % 2 == 1
result = (result * base) % modulo
base = (base * base) % modulo
power //= 2
return result
#Even position can have 5 choices 0,2,4,6,8
even_digit_choices = 5
#Odd positions can have 4 choices 2,3,5,7
odd_digit_choices = 4
number_of_even_positions = (number + 1) // 2
number_of_odd_positions = number // 2
# Calculating the combinations using exponentiation by squaring
even_combinations = fast_power(even_digit_choices, number_of_even_positions)
odd_combinations = fast_power(odd_digit_choices, number_of_odd_positions)
# Multiplying even and odd combinations to calculate final answer
total_good_numbers = (even_combinations * odd_combinations) % modulo
return total_good_numbers| Case | How to Handle |
|---|---|
| n = 0 | Return 1 since there is one way to form a 'good' number of length 0 (empty string). |
| n = 1 | Return 5 since any of the odd digits (1, 3, 5, 7, 9) can occupy the first position. |
| Large value of n causing potential integer overflow | Use modular exponentiation with long type or BigInteger to prevent overflow. |
| n is a very large even number | Modular exponentiation will handle arbitrarily large even numbers efficiently, as it breaks down the exponent. |
| n is a very large odd number | Modular exponentiation handles large odd numbers by calculating base^(n-1) * base. |
| Result overflows after multiplying even and odd powers | Apply the modulo operator after each multiplication to prevent intermediate overflow. |
| Modulo is 1 | Return 0, as every number modulo 1 will be 0. |
| n is negative | Treat as invalid input and throw an exception or return a predefined error value (e.g., -1). |