Count N-digit numbers whose digits does not exceed absolute difference of the two previous digits

Given an integer N, the task is to count the number of N-digit numbers such that each digit, except the first and second digits, is less than or equal to the absolute difference of the previous two digits.
Examples:
Input: N = 1
Output: 10
Explanation: All the numbers from [0 – 9] are valid because the number of digits is 1.Input : N = 3
Output : 375
Naive Approach: The simplest approach is to iterate over all possible N-digit numbers and for each such numbers, check if all its digits satisfy the above condition or not.Â
Time Complexity: O(10N*N)
Auxiliary Space: O(1)
Efficient Approach: In the efficient approach, all possible numbers are constructed instead of verifying the conditions on a range of numbers. This can be achieved with the help of Dynamic Programming because it has overlapping subproblems and optimal substructure. The subproblems can be stored in dp[][][] table using memoization where dp[digit][prev1][prev2] stores the answer from the digit-th position till the end, when the previous digit selected, is prev1 and the second most previous digit selected is prev2.
Follow the below steps to solve the problem:
- Define a recursive function countOfNumbers(digit, prev1, prev2) by performing the following steps.
- Check the base cases. If the value of digit is equal to N+1 then return 1 as a valid N-digit number is formed.
- If the result of the state dp[digit][prev1][prev2] is already computed, return this state dp[digit][prev1][prev2].
- If the current digit is 1, then any digit from [1-9] can be placed. If N=1, then 0 can be placed as well.
- If the current digit is 2, then any digit from [0-9] can be placed.
- Else any number from [0-(abs(prev1-prev2))] can be placed at the current position.
- 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 answer.
Below is the code for the above approach:
C++
// C++ program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
long long dp[50][10][10];Â
// Function to count N digit numbers whose// digits are less than or equal to the// absolute difference of previous two digitslong long countOfNumbers(int digit, int prev1,                         int prev2, int N){    // If all digits are traversed    if (digit == N + 1)        return 1;Â
    // If the state has already been computed    if (dp[digit][prev1][prev2] != -1)        return dp[digit][prev1][prev2];Â
    dp[digit][prev1][prev2] = 0;Â
    // If the current digit is 1,    // any digit from [1-9] can be placed.    // If N==1, 0 can also be placed.    if (digit == 1) {        for (int j = (N == 1 ? 0 : 1);             j <= 9; ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(digit + 1,                                  j, prev1, N);        }    }Â
    // If the current digit is 2, any    // digit from [0-9] can be placed    else if (digit == 2) {        for (int j = 0; j <= 9; ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(                    digit + 1, j, prev1, N);        }    }Â
    // For other digits, any digit    // from 0 to abs(prev1 - prev2) can be placed    else {        for (int j = 0; j <= abs(prev1 - prev2); ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(digit + 1, j, prev1, N);        }    }Â
    // Return the answer    return dp[digit][prev1][prev2];}Â
// Driver codeint main(){    // Initializing dp array with -1.    memset(dp, -1, sizeof dp);Â
    // Input    int N = 3;Â
    // Function call    cout << countOfNumbers(1, 0, 0, N) << endl;Â
    return 0;} |
Java
// Java program for the above approachimport java.util.*;Â
class GFG{Â Â Â Â Â static int dp[][][] = new int[50][10][10];Â
static void initialize(){    for(int i = 0; i < 50; i++)    {        for(int j = 0; j < 10; j++)        {            for(int k = 0; k < 10; k++)            {                dp[i][j][k] = -1;            }        }    }}  // Function to count N digit numbers whose// digits are less than or equal to the// absolute difference of previous two digitsstatic int countOfNumbers(int digit, int prev1,                          int prev2, int N){         // If all digits are traversed    if (digit == N + 1)        return 1;      // If the state has already been computed    if (dp[digit][prev1][prev2] != -1)        return dp[digit][prev1][prev2];      dp[digit][prev1][prev2] = 0;      // If the current digit is 1,    // any digit from [1-9] can be placed.    // If N==1, 0 can also be placed.    if (digit == 1)     {        for(int j = (N == 1 ? 0 : 1);                j <= 9; ++j)         {            dp[digit][prev1][prev2] += countOfNumbers(                digit + 1, j, prev1, N);        }    }      // If the current digit is 2, any    // digit from [0-9] can be placed    else if (digit == 2)     {        for(int j = 0; j <= 9; ++j)         {            dp[digit][prev1][prev2] += countOfNumbers(                    digit + 1, j, prev1, N);        }    }      // For other digits, any digit    // from 0 to abs(prev1 - prev2) can be placed    else    {        for(int j = 0; j <= Math.abs(prev1 - prev2); ++j)        {            dp[digit][prev1][prev2] += countOfNumbers(                digit + 1, j, prev1, N);        }    }      // Return the answer    return dp[digit][prev1][prev2];}     // Driver Codepublic static void main(String[] args){    initialize();          // Input    int N = 3;      // Function call    System.out.print(countOfNumbers(1, 0, 0, N));}}Â
// This code is contributed by susmitakundugoaldanga |
Python3
# Python3 program for the above approachdp = [[[-1 for i in range(10)] Â Â Â Â Â Â Â Â Â Â Â for j in range(10)] Â Â Â Â Â Â Â Â Â Â Â for k in range(50)]Â
# Function to count N digit numbers whose# digits are less than or equal to the# absolute difference of previous two digitsdef countOfNumbers(digit, prev1, prev2, N):         # If all digits are traversed    if (digit == N + 1):        return 1Â
    # If the state has already been computed    if (dp[digit][prev1][prev2] != -1):        return dp[digit][prev1][prev2]Â
    dp[digit][prev1][prev2] = 0Â
    # If the current digit is 1,    # any digit from [1-9] can be placed.    # If N==1, 0 can also be placed.    if (digit == 1):        term = 0 if N == 1 else 1                 for j in range(term, 10, 1):            dp[digit][prev1][prev2] += countOfNumbers(                digit + 1, j, prev1, N)Â
    # If the current digit is 2, any    # digit from [0-9] can be placed    elif (digit == 2):        for j in range(10):            dp[digit][prev1][prev2] += countOfNumbers(                digit + 1, j, prev1, N)Â
    # For other digits, any digit    # from 0 to abs(prev1 - prev2) can be placed    else:        for j in range(abs(prev1 - prev2) + 1):            dp[digit][prev1][prev2] += countOfNumbers(                digit + 1, j, prev1, N)Â
    # Return the answer    return dp[digit][prev1][prev2]Â
# Driver codeif __name__ == '__main__':         # Input    N = 3         # Function call    print(countOfNumbers(1, 0, 0, N))     # This code is contributed by ipg2016107 |
C#
// C# program for the above approachusing System;using System.Collections.Generic;Â
class GFG{Â
static int [,,]dp = new int[50, 10, 10];Â
static void initialize(){Â Â Â Â for(int i = 0; i < 50; i++)Â Â Â Â {Â Â Â Â Â Â Â Â for(int j = 0; j < 10; j++)Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â for(int k = 0; k < 10; k++)Â Â Â Â Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â dp[i, j, k] = -1;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }}Â
// Function to count N digit numbers whose// digits are less than or equal to the// absolute difference of previous two digitsstatic int countOfNumbers(int digit, int prev1,                          int prev2, int N){         // If all digits are traversed    if (digit == N + 1)        return 1;Â
    // If the state has already been computed    if (dp[digit, prev1, prev2] != -1)        return dp[digit, prev1, prev2];Â
    dp[digit, prev1, prev2] = 0;Â
    // If the current digit is 1,    // any digit from [1-9] can be placed.    // If N==1, 0 can also be placed.    if (digit == 1)     {        for(int j = (N == 1 ? 0 : 1);                j <= 9; ++j)        {            dp[digit, prev1, prev2] += countOfNumbers(                              digit + 1, j, prev1, N);        }    }Â
    // If the current digit is 2, any    // digit from [0-9] can be placed    else if (digit == 2)    {        for(int j = 0; j <= 9; ++j)         {            dp[digit, prev1, prev2] += countOfNumbers(                              digit + 1, j, prev1, N);        }    }Â
    // For other digits, any digit    // from 0 to abs(prev1 - prev2)    // can be placed    else    {        for(int j = 0; j <= Math.Abs(prev1 - prev2); ++j)         {            dp[digit, prev1, prev2] += countOfNumbers(                              digit + 1, j, prev1, N);        }    }Â
    // Return the answer    return dp[digit, prev1, prev2];}Â
// Driver codepublic static void Main(){    initialize();         // Input    int N = 3;Â
    // Function call    Console.Write(countOfNumbers(1, 0, 0, N));}}Â
// This code is contributed by SURENDRA_GANGWAR |
Javascript
<script>Â
// JavaScript program for the above approachÂ
Â
var dp = Array.from(Array(50), ()=>Array(10));for(var i =0; i<10; i++)Â Â Â Â Â Â Â Â for(var j =0; j<10; j++)Â Â Â Â Â Â Â Â Â Â Â Â dp[i][j] = new Array(10).fill(-1); Â
// Function to count N digit numbers whose// digits are less than or equal to the// absolute difference of previous two digitsfunction countOfNumbers(digit, prev1, prev2, N){    // If all digits are traversed    if (digit == N + 1)        return 1;Â
    // If the state has already been computed    if (dp[digit][prev1][prev2] != -1)        return dp[digit][prev1][prev2];Â
    dp[digit][prev1][prev2] = 0;Â
    // If the current digit is 1,    // any digit from [1-9] can be placed.    // If N==1, 0 can also be placed.    if (digit == 1) {        for (var j = (N == 1 ? 0 : 1);             j <= 9; ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(digit + 1,                                  j, prev1, N);        }    }Â
    // If the current digit is 2, any    // digit from [0-9] can be placed    else if (digit == 2) {        for (var j = 0; j <= 9; ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(                    digit + 1, j, prev1, N);        }    }Â
    // For other digits, any digit    // from 0 to abs(prev1 - prev2) can be placed    else {        for (var j = 0; j <= Math.abs(prev1 - prev2); ++j) {Â
            dp[digit][prev1][prev2]                += countOfNumbers(digit + 1, j, prev1, N);        }    }Â
    // Return the answer    return dp[digit][prev1][prev2];}Â
// Driver codeÂ
// Inputvar N = 3;Â
// Function calldocument.write( countOfNumbers(1, 0, 0, N));Â
</script> |
375
Â
Time Complexity : O(N * 103)
Auxiliary Space: O(N * 102)Â
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



