Start learning free

LESSON 342 OF 409 · DYNAMIC PROGRAMMING

Numbers with Digit Product P in C++ (Time Complexity Analysis Included)

Practice O(n * p * digits) Read the full explanation

Given two non-negative integers n and p, return the number of base-10 numbers with n digits and with the digit product equal to p

Example:

Input: n = 3, p = 6
Output: 9
Explanation: [
    123,
    132,
    213,
    231,
    312,
    321,
    116,
    161,
    611
]
Notes:
n <= 12
STEP 1 OF 10
    Ctrl + Enter to check

    C++ · DYNAMIC PROGRAMMING

    Digit Product Numbers in C++, explained

    Understanding the Problem

    The core challenge of this problem is to find all possible numbers with exactly N digits such that the product of their digits equals P. This problem is significant in combinatorial number theory and has applications in cryptography and digital signal processing.

    Potential pitfalls include handling cases where P is zero or very large, and ensuring that the numbers have exactly N digits (leading zeros are not allowed).

    Approach

    To solve this problem, we need to generate all possible numbers with N digits and check if their digit product equals P. A naive solution would involve generating all possible numbers and checking each one, but this is not efficient.

    Instead, we can use a recursive approach to build numbers digit by digit, ensuring that the product of the digits remains equal to P. This reduces the number of checks and improves efficiency.

    Naive Solution

    The naive solution involves generating all possible N-digit numbers and checking if their digit product equals P. This approach is not optimal due to its high time complexity.

    Optimized Solution

    We can optimize the solution using a recursive function that builds numbers digit by digit. At each step, we multiply the current product by the next digit and check if it equals P. If it does, we count the number. This approach significantly reduces the number of checks.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Define a recursive function that takes the current number, the current product, and the number of digits left to add.
    2. At each step, iterate through digits 1 to 9 (since 0 cannot be a leading digit).
    3. Multiply the current product by the current digit and check if it equals P.
    4. If the product equals P and the number of digits left is zero, increment the count.
    5. Otherwise, recursively call the function with the updated product and one less digit to add.

    Code Implementation

    
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    // Recursive function to count numbers with N digits and product P
    void countNumbers(int N, int P, int currentProduct, int currentDigits, int& count) {
        // Base case: if we have used all digits
        if (currentDigits == N) {
            if (currentProduct == P) {
                count++;
            }
            return;
        }
    
        // Try each digit from 1 to 9
        for (int digit = 1; digit <= 9; digit++) {
            // Avoid overflow
            if (currentProduct * digit <= P) {
                countNumbers(N, P, currentProduct * digit, currentDigits + 1, count);
            }
        }
    }
    
    int main() {
        int N = 3;
        int P = 6;
        int count = 0;
    
        // Start the recursive function
        countNumbers(N, P, 1, 0, count);
    
        cout << "Number of " << N << "-digit numbers with product " << P << " is: " << count << endl;
    
        return 0;
    }
    

    Complexity Analysis

    The time complexity of the optimized solution is O(9^N), where 9 is the number of possible digits (1-9) and N is the number of digits. This is a significant improvement over the naive approach, which has a time complexity of O(10^N).

    The space complexity is O(N) due to the recursion stack.

    Edge Cases

    Potential edge cases include:

    • P is zero: No valid numbers exist.
    • P is very large: The function should handle large products without overflow.
    • N is zero: The function should return zero as no digits are allowed.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases: N = 1, P = 5
    • Edge cases: N = 0, P = 0
    • Complex cases: N = 3, P = 6

    Use a variety of test cases to ensure the solution handles all scenarios correctly.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider breaking down the problem into smaller sub-problems and using recursion to solve them. Practice solving similar problems to improve your problem-solving skills.

    Conclusion

    Understanding and solving combinatorial problems like this one is crucial for developing strong problem-solving skills. Practice and explore further to enhance your understanding.

    Additional Resources

    For further reading and practice problems, consider the following resources:

    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free