Open In App

Count of strictly increasing N-digit numbers

Last Updated : 17 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given a positive integer N, the task is to find the number of N-digit numbers such that every digit is smaller than its adjacent digits.

Examples:

Input: N = 1
Output: 10
Explanation: All numbers from [0 – 9] satisfy the condition as there is only one digit.

Input: N = 3
Output: 525

Naive Approach: The simplest approach to solve the given problem is to iterate over all possible N-digit numbers and for each such number, check if all its digits satisfy the given criteria or not. If found to be true, then count these numbers. After checking for all the numbers print the total count obtained.

Time Complexity: O(10N*N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by using Dynamic Programming because it has overlapping subproblems and optimal substructure. The subproblems can be stored in dp[][][] table using memoization where dp[i][prev][sign] stores the result from the ith position till the end, when the previous digit selected, is prev and the variable sign is used to indicate if the current digit must be lesser or greater than the previous digit. Follow the steps below to solve the problem:

  • Define a recursive function, say, countOfNumbers(digit, prev, sign) with three parameters: digit, sign and prev.
    • Check for the base cases, i.e., if the value of i is equal to N then return 1 as a valid N-digit number is formed.
    • Initialize a variable, say, val = 0, to store all possible counts of N-digit numbers.
    • If i is 0, then any digit from [1 – 9] can be placed, and also if N = 1, then 0 can be placed as well.
    • If i is 1, then any digit from [0 – 9] can be placed such that the current digit is not equal to the previous one.
    • If the value of the sign is 1, then place the current digit such that it is less than the previous digit and change the sign to 0 for the next recursive call.
    • If the value of the sign is 0, then place the current digit such that it is more than the previous digit and change the sign to 1 for the next recursive call.
    • After making a valid placement, recursively call the countOfNumbers function for index (digit + 1).
    • Return the sum of all possible valid placements of digits as the result of each current recursive call.
  • After the above steps, print the value returned by the function countOfNumbers(0, N, 0, 0) as the resultant count.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Declaration of dp table
int dp[100][10][2];
 
// Function to find the count of all N
// digit numbers such that all the digit
// is less than its adjacent digits
int solve(int i, int n, int prev, bool sign)
{
    // Base Case:
    // If i = n, then return 1 as valid
    // number has been formed
    if (i == n) {
        return 1;
    }
 
    int& val = dp[i][prev][sign];
 
    // If the state has already been
    // computed, then return it
    if (val != -1)
        return val;
 
    // Stores the total count of ways
    // for the current recursive call
    val = 0;
 
    // If i = 0, any digit from [1-9]
    // can  be placed and also if N = 1
    //, then 0 can also be placed
    if (i == 0) {
        for (int digit = (n == 1 ? 0 : 1);
             digit <= 9;
             ++digit) {
            val += solve(i + 1, n,
                         digit, sign);
        }
    }
 
    // If i = 1, any digit from [0-9]
    // can be placed such that digit
    // is not equal to previous digit
    else if (i == 1) {
        for (int digit = 0; digit <= 9;
             ++digit) {
 
            // If the current digit is
            // not same as the prev
            if (digit != prev) {
                val += solve(i + 1, n, digit,
                             (digit > prev));
            }
        }
    }
 
    else {
 
        // Place the current digit such
        // that it is less than the
        // previous digit
        if (sign == 1) {
            for (int digit = prev - 1;
                 digit >= 0;
                 --digit) {
 
                val += solve(i + 1, n,
                             digit, 0);
            }
        }
 
        // Place current digit such
        // that it is more than the
        // previous digit
        else {
            for (int digit = prev + 1;
                 digit <= 9;
                 ++digit) {
 
                val += solve(i + 1, n,
                             digit, 1);
            }
        }
    }
 
    // Return the resultant total count
    return val;
}
 
// Function to find all N-digit numbers
// satisfying the given criteria
void countNdigitNumber(int N)
{
 
    // Initialize an array dp[] with
    // all elements as -1
    memset(dp, -1, sizeof dp);
 
    // Function call to count all
    // possible ways
    cout << solve(0, N, 0, 0);
}
 
// Driver Code
int main()
{
    int N = 3;
    countNdigitNumber(N);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
public class MyClass
{
 
// Declaration of dp table
static int[][][] dp = new int[100][10][2];
 
// Function to find the count of all N
// digit numbers such that all the digit
// is less than its adjacent digits
static int solve(int i, int n, int prev, int sign)
{
   
    // Base Case:
    // If i = n, then return 1 as valid
    // number has been formed
    if (i == n) {
        return 1;
    }
 
    int val = dp[i][prev][sign];
 
    // If the state has already been
    // computed, then return it
    if (val != -1)
        return val;
 
    // Stores the total count of ways
    // for the current recursive call
    val = 0;
 
    // If i = 0, any digit from [1-9]
    // can  be placed and also if N = 1
    //, then 0 can also be placed
    if (i == 0) {
        for (int digit = (n == 1 ? 0 : 1);
             digit <= 9;
             ++digit) {
            val += solve(i + 1, n,
                         digit, sign);
        }
    }
 
    // If i = 1, any digit from [0-9]
    // can be placed such that digit
    // is not equal to previous digit
    else if (i == 1) {
        for (int digit = 0; digit <= 9;
             ++digit) {
 
            // If the current digit is
            // not same as the prev
            if (digit != prev) {
                val += solve(i + 1, n, digit,((digit > prev)?1:0));
            }
        }
    }
 
    else {
 
        // Place the current digit such
        // that it is less than the
        // previous digit
        if (sign == 1) {
            for (int digit = prev - 1;
                 digit >= 0;
                 --digit) {
 
                val += solve(i + 1, n,
                             digit, 0);
            }
        }
 
        // Place current digit such
        // that it is more than the
        // previous digit
        else {
            for (int digit = prev + 1;
                 digit <= 9;
                 ++digit) {
 
                val += solve(i + 1, n,
                             digit, 1);
            }
        }
    }
 
    // Return the resultant total count
    return val;
}
 
// Function to find all N-digit numbers
// satisfying the given criteria
static void countNdigitNumber(int N)
{
 
    // Initialize an array dp[] with
    // all elements as -1
    for (int[][] row : dp)
    {
        for (int[] rowColumn : row)
        {
            Arrays.fill(rowColumn, -1);
        }
    }
    // Function call to count all
    // possible ways
     System.out.println(solve(0, N, 0, 0));
}
 
// Driver Code
 public static void main(String args[])
{
    int N = 3;
    countNdigitNumber(N);
}
}
 
// This code is contributed by SoumikMondal


Python3




# python 3 program for the above approach
 
# Declaration of dp table
dp = [[[-1 for x in range(2)] for y in range(10)] for z in range(100)]
 
# Function to find the count of all N
# digit numbers such that all the digit
# is less than its adjacent digits
def solve(i,  n,  prev,  sign):
 
    # Base Case:
    # If i = n, then return 1 as valid
    # number has been formed
    if (i == n):
        return 1
 
    val = dp[i][prev][sign]
 
    # If the state has already been
    # computed, then return it
    if (val != -1):
        return val
 
    # Stores the total count of ways
    # for the current recursive call
    val = 0
 
    # If i = 0, any digit from [1-9]
    # can  be placed and also if N = 1
    # , then 0 can also be placed
    if (i == 0):
        if (n == 1):
            digit = 0
        else:
            digit = 1
        while digit <= 9:
 
            val += solve(i + 1, n,
                         digit, sign)
            digit += 1
 
    # If i = 1, any digit from [0-9]
    # can be placed such that digit
    # is not equal to previous digit
    elif (i == 1):
        for digit in range(10):
 
            # If the current digit is
            # not same as the prev
            if (digit != prev):
                val += solve(i + 1, n, digit,
                             (digit > prev))
 
    else:
 
        # Place the current digit such
        # that it is less than the
        # previous digit
        if (sign == 1):
            for digit in range(prev - 1,
                               -1, -1):
 
                val += solve(i + 1, n,
                             digit, 0)
 
        # Place current digit such
        # that it is more than the
        # previous digit
        else:
            for digit in range(prev + 1, 10):
 
                val += solve(i + 1, n,
                             digit, 1)
 
    # Return the resultant total count
    return val
 
# Function to find all N-digit numbers
# satisfying the given criteria
def countNdigitNumber(N):
 
    # Initialize an array dp[] with
    # all elements as -1
 
    # Function call to count all
    # possible ways
    print(solve(0, N, 0, 0))
 
# Driver Code
if __name__ == "__main__":
 
    N = 3
    countNdigitNumber(N)
 
    # This code is contributed by ukasp.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class MyClass
{
 
// Declaration of dp table
static int[,,] dp = new int[100,10,2];
 
// Function to find the count of all N
// digit numbers such that all the digit
// is less than its adjacent digits
static int solve(int i, int n, int prev, int sign)
{
   
    // Base Case:
    // If i = n, then return 1 as valid
    // number has been formed
    if (i == n) {
        return 1;
    }
 
    int val = dp[i,prev,sign];
 
    // If the state has already been
    // computed, then return it
    if (val != -1)
        return val;
 
    // Stores the total count of ways
    // for the current recursive call
    val = 0;
 
    // If i = 0, any digit from [1-9]
    // can  be placed and also if N = 1
    //, then 0 can also be placed
    if (i == 0) {
        for (int digit = (n == 1 ? 0 : 1);
             digit <= 9;
             ++digit) {
            val += solve(i + 1, n,
                         digit, sign);
        }
    }
 
    // If i = 1, any digit from [0-9]
    // can be placed such that digit
    // is not equal to previous digit
    else if (i == 1) {
        for (int digit = 0; digit <= 9;
             ++digit) {
 
            // If the current digit is
            // not same as the prev
            if (digit != prev) {
                val += solve(i + 1, n, digit,((digit > prev)?1:0));
            }
        }
    }
 
    else {
 
        // Place the current digit such
        // that it is less than the
        // previous digit
        if (sign == 1) {
            for (int digit = prev - 1;
                 digit >= 0;
                 --digit) {
 
                val += solve(i + 1, n,
                             digit, 0);
            }
        }
 
        // Place current digit such
        // that it is more than the
        // previous digit
        else {
            for (int digit = prev + 1;
                 digit <= 9;
                 ++digit) {
 
                val += solve(i + 1, n,
                             digit, 1);
            }
        }
    }
 
    // Return the resultant total count
    return val;
}
 
// Function to find all N-digit numbers
// satisfying the given criteria
static void countNdigitNumber(int N)
{
 
    // Initialize an array []dp with
    // all elements as -1
    for(int i = 0;i<100;i++)
{
    for (int j = 0; j < 10; j++) {
        for (int k = 0; k < 2; k++)
            dp[i,j,k] = -1;
    }
}
    // Function call to count all
    // possible ways
     Console.WriteLine(solve(0, N, 0, 0));
}
 
// Driver Code
 public static void Main(String []args)
{
    int N = 3;
    countNdigitNumber(N);
}
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
// javascript program for the above approach
 
    // Declaration of dp table
     var dp = Array(100).fill().map(()=>Array(10).fill().map(()=>Array(2).fill(-1)));
 
    // Function to find the count of all N
    // digit numbers such that all the digit
    // is less than its adjacent digits
    function solve(i , n , prev , sign) {
 
        // Base Case:
        // If i = n, then return 1 as valid
        // number has been formed
        if (i == n) {
            return 1;
        }
 
        var val = dp[i][prev][sign];
 
        // If the state has already been
        // computed, then return it
        if (val != -1)
            return val;
 
        // Stores the total count of ways
        // for the current recursive call
        val = 0;
 
        // If i = 0, any digit from [1-9]
        // can be placed and also if N = 1
        // , then 0 can also be placed
        if (i == 0) {
            for (var digit = (n == 1 ? 0 : 1); digit <= 9; ++digit) {
                val += solve(i + 1, n, digit, sign);
            }
        }
 
        // If i = 1, any digit from [0-9]
        // can be placed such that digit
        // is not equal to previous digit
        else if (i == 1) {
            for (var digit = 0; digit <= 9; ++digit) {
 
                // If the current digit is
                // not same as the prev
                if (digit != prev) {
                    val += solve(i + 1, n, digit, ((digit > prev) ? 1 : 0));
                }
            }
        }
 
        else {
 
            // Place the current digit such
            // that it is less than the
            // previous digit
            if (sign == 1) {
                for (var digit = prev - 1; digit >= 0; --digit) {
 
                    val += solve(i + 1, n, digit, 0);
                }
            }
 
            // Place current digit such
            // that it is more than the
            // previous digit
            else {
                for (var digit = prev + 1; digit <= 9; ++digit) {
 
                    val += solve(i + 1, n, digit, 1);
                }
            }
        }
 
        // Return the resultant total count
        return val;
    }
 
    // Function to find all N-digit numbers
    // satisfying the given criteria
    function countNdigitNumber(N) {
 
        // Function call to count all
        // possible ways
        document.write(solve(0, N, 0, 0));
    }
 
    // Driver Code
     
        var N = 3;
        countNdigitNumber(N);
 
// This code is contributed by gauravrajput1
</script>


Output: 

525

 

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads