Count Good Numbers

Solution For Count Good Numbers

Problem Statement:

A digit string is good if the sum of its digits is even or the product of its digits is odd.

Given an integer n, return the count of all good digit strings of length n. Since the answer may be large, return it modulo 10^9 + 7.

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

Approach:

We can solve this problem using dynamic programming. Let’s define two arrays:

even[i] – the number of good digit strings of length i whose sum of digits is even
odd[i] – the number of good digit strings of length i whose product of digits is odd
Let’s start with i=1.

even[1] = 5 because we have five even digits (0, 2, 4, 6, 8).
odd[1] = 5 because we have five odd digits (1, 3, 5, 7, 9).

Now let’s move to i=2. We can use the values of even[1] and odd[1] to calculate even[2] and odd[2].

even[2] can be calculated as the sum of the number of good digit strings of length 1 that end with an even digit multiplied by 5. Why? Because we can append any even digit to the end of a good digit string of length 1 whose sum of digits is even and we get a good digit string of length 2 whose sum of digits is even. For example, if we have “0” in the previous step, we can append any even digit (0, 2, 4, 6, 8) to get “00”, “02”, “04”, “06”, “08” which are all good digit strings of length 2 whose sum of digits is even. Similarly, we can append any odd digit (1, 3, 5, 7, 9) to the end of a good digit string of length 1 whose product of digits is odd and we get a good digit string of length 2 whose product of digits is odd. So:

even[2] = 5 * odd[1] = 25
odd[2] = even[1] + 5 * even[1] = 30
Let’s move to i=3 and calculate even[3] and odd[3]:

even[3] = 5 * odd[2] = 5 * (even[1] + 5 * even[1]) = 125
odd[3] = even[2] + 5 * even[2] = 175
And so on, we can keep calculating even[i] and odd[i] using the values of even[i-1] and odd[i-1] until we reach the target length n.

Finally, the answer is the sum of even[n] and odd[n] because any good digit string of length n either has a sum of digits that is even or a product of digits that is odd.

Below is the implementation of this approach:

class Solution {
public int countGoodNumbers(long n) {
long MOD = 1000000007;
long[] even = new long[51];
long[] odd = new long[51];
even[1] = 5;
odd[1] = 5;
for (int i = 2; i <= n; i++) {
even[i] = (5 * odd[i-1]) % MOD;
odd[i] = (even[i-1] + 5 * even[i-1]) % MOD;
}
return (int) ((even[(int) n] + odd[(int) n]) % MOD);
}
}

Time Complexity: O(n)

Space Complexity: O(n)

Step by Step Implementation For Count Good Numbers

/**
 * Given an integer n. Each number from 1 to n is grouped according to the sum of its digits. 
 * Return how many groups have the largest size.
 * 
 * @param n
 * @return count
 */
public int countLargestGroup(int n) {
    // create a map to store the sum of digits as key and count of corresponding numbers as value
    Map map = new HashMap();
    
    // iterate through all numbers from 1 to n
    for(int i = 1; i <= n; i++) {
        // calculate sum of digits for each number
        int sum = getSumOfDigits(i);
        
        // if map already contains the key, increment the count
        if(map.containsKey(sum)) {
            map.put(sum, map.get(sum) + 1);
        // else, set the count as 1
        } else {
            map.put(sum, 1);
        }
    }
    
    // get the maximum value in the map
    int max = Collections.max(map.values());
    
    // return the count of numbers having maximum value
    return Collections.frequency(map.values(), max);
}

/**
 * Helper method to get the sum of digits of a number
 * 
 * @param num
 * @return sum
 */
public int getSumOfDigits(int num) {
    int sum = 0;
    
    // loop through all digits of the number
    // add the digits to the sum
    while(num > 0) {
        sum = sum + (num % 10);
        num = num / 10;
    }
    
    return sum;
}
def countGoodNumbers(low, high): 

# Create an empty list 
    list = [] 

# Loop from low to high 
    for num in range(low, high + 1): 

# Initialize sum 
        digitSum = 0

# Find sum of digits 
        temp = num 
        while temp > 0: 
            digit = temp % 10
            digitSum += digit 
            temp //= 10

# If sum is less than 10, 
# then number is good 
        if digitSum < 10: 
            list.append(num) 

# Print the list 
    return list
//Solution:

var countGoodNumbers = function(l, r) {
    let count = 0;
    
    for (let i = l; i <= r; i++) {
        let num = i;
        let sum = 0;
        
        while (num > 0) {
            sum += num % 10;
            num = Math.floor(num / 10);
        }
        
        if (sum % 10 === 0) {
            count++;
        }
    }
    
    return count;
};
int countGoodNumbers(int l, int r) 
{ 
    int cnt = 0; 
    for (int n = l; n <= r; n++) 
        if (isGood(n)) 
            cnt++; 
    return cnt; 
} 
  
// A good number is a number whose sum of digits 
// is divisible by 10 
bool isGood(int n) 
{ 
    int sum = 0; 
    while (n) 
    { 
        sum += n % 10; 
        n /= 10; 
    } 
    return (sum % 10 == 0); 
}
public int CountGoodNumbers(int lower, int upper) 
{ 
    int count = 0; 
    for(int i = lower; i <= upper; i++) 
    { 
        if (isGoodNumber(i)) 
        { 
            count++; 
        } 
    } 
    return count; 
} 

// A number is good if the sum of its digits is less than or equal to 10. 
public bool isGoodNumber(int n) 
{ 
    int sum = 0; 
    while (n > 0) 
    { 
        sum += n % 10; 
        n /= 10; 
    } 
    return (sum <= 10); 
}


Scroll to Top
[gravityforms id="5" description="false" titla="false" ajax="true"]