Skip to content
Related Articles

Related Articles

Improve Article

Count of strictly increasing N-digit numbers

  • Last Updated : 09 Aug, 2021

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
Output: 
525

 

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :