Count of N-digit numbers with absolute difference of adjacent digits not exceeding K | Set 2

• Difficulty Level : Expert
• Last Updated : 18 Aug, 2021

Given two integers N and K, the task is to find the count of N-digit numbers such that the absolute difference of adjacent digits in the number is not greater than K.
Examples:

Input: N = 2, K = 1
Output: 26
Explanation: The numbers are 10, 11, 12, 21, 22, 23, 32, 33, 34, 43, 44, 45, 54, 55, 56, 65, 66, 67, 76, 77, 78, 87, 88, 89, 98, 99
Input: N = 3, K = 2
Output: 188

Naive Approach and Dynamic Programming Approach: Refer to Count of N-digit numbers with absolute difference of adjacent digits not exceeding K for the simplest solution and the dynamic programming approach that requires O(N) auxiliary space.
Space-Efficient Approach:
Follow the steps below to optimize the above approach:

• In the above approach, a 2D array dp[][] is initialized where dp[i][j] stores the count of numbers having i digits and ending with j.
• It can be observed that the answer for any length i depends only on the count generated for i – 1. So, instead of a 2D array, initialize an array dp[] of size of all possible digits, and for every i upto N, dp[j] stores count of such numbers of length i ending with digit j.
• Initialize another array next[] of size of all possible digits.
• Since the count of single-digit numbers ending with a value j is always 1, fill dp[] with 1 at all indices initially.
• Iterate over the range [2, N], and for every value in the range i, check if the last digit is j, then the allowed digits for this place are in the range (max(0, j-k), min(9, j+k)). Perform a range update:

next[l] = next[l] + dp[j]
next[r + 1] = next[r + 1] – dp[j]
where l and r are max(0, j – k) and min(9, j + k) respectively.

• Once the above step is completed for a particular value of i, compute prefix sum of next[] and update dp[] with the values of next[].

Below is the implementation of the above approach:

C

 // C program to implement the above approach#include  // Function to find maximum between two numbersint max(int num1, int num2){    return (num1 > num2 ) ? num1 : num2;} // Function to find minimum between two numbersint min(int num1, int num2){    return (num1 > num2 ) ? num2 : num1;} // Function to return the count// of such numbersint getCount(int n, int k){         // For 1-digit numbers, the count    // is 10 irrespective of K    if (n == 1)        return 10;     // dp[j] stores the number    // of such i-digit numbers    // ending with j    int dp = {0};     // Stores the results of length i    int next = {0};             // Initialize count for    // 1-digit numbers    for(int i = 1; i <= 9; i++)        dp[i] = 1;     // Compute values for count of    // digits greater than 1    for(int i = 2; i <= n; i++)    {        for(int j = 0; j <= 9; j++)        {             // Find the range of allowed            // numbers if last digit is j            int l = max(0, (j - k));            int r = min(9, (j + k));             // Perform Range update            next[l] += dp[j];            next[r + 1] -= dp[j];        }         // Prefix sum to find actual count        // of i-digit numbers ending with j        for(int j = 1; j <= 9; j++)            next[j] += next[j - 1];         // Update dp[]        for(int j = 0; j < 10; j++)        {            dp[j] = next[j];            next[j] = 0;        }    }     // Stores the final answer    int count = 0;    for(int i = 0; i <= 9; i++)        count += dp[i];     // Return the final answer    return count;} // Driver Codeint main(){    int n = 2, k = 1;    printf("%d", getCount(n, k));} // This code is contributed by piyush3010.

C++

 // C++ Program to implement// the above approach#include using namespace std; // Function to find maximum between two numbersint max(int num1, int num2){    return (num1 > num2 ) ? num1 : num2;}  // Function to find minimum between two numbersint min(int num1, int num2){    return (num1 > num2 ) ? num2 : num1;}  // Function to return the count// of such numbersint getCount(int n, int k){          // For 1-digit numbers, the count    // is 10 irrespective of K    if (n == 1)        return 10;      // dp[j] stores the number    // of such i-digit numbers    // ending with j    int dp = {0};      // Stores the results of length i    int next = {0};              // Initialize count for    // 1-digit numbers    for(int i = 1; i <= 9; i++)        dp[i] = 1;      // Compute values for count of    // digits greater than 1    for(int i = 2; i <= n; i++)    {        for(int j = 0; j <= 9; j++)        {              // Find the range of allowed            // numbers if last digit is j            int l = max(0, (j - k));            int r = min(9, (j + k));              // Perform Range update            next[l] += dp[j];            next[r + 1] -= dp[j];        }          // Prefix sum to find actual count        // of i-digit numbers ending with j        for(int j = 1; j <= 9; j++)            next[j] += next[j - 1];          // Update dp[]        for(int j = 0; j < 10; j++)        {            dp[j] = next[j];            next[j] = 0;        }    }      // Stores the final answer    int count = 0;    for(int i = 0; i <= 9; i++)        count += dp[i];      // Return the final answer    return count;} // Driver Codeint main(){    int n = 2, k = 1;    cout <<  getCount(n, k);     return 0;}

Java

 // Java Program to implement// the above approachimport java.util.*;class GFG {     // Function to return the count    // of such numbers    public static long getCount(        int n, int k)    {        // For 1-digit numbers, the count        // is 10 irrespective of K        if (n == 1)            return 10;         // dp[j] stores the number        // of such i-digit numbers        // ending with j        long dp[] = new long;         // Stores the results of length i        long next[] = new long;         // Initialize count for        // 1-digit numbers        for (int i = 1; i <= 9; i++)            dp[i] = 1;         // Compute values for count of        // digits greater than 1        for (int i = 2; i <= n; i++) {            for (int j = 0; j <= 9; j++) {                 // Find the range of allowed                // numbers if last digit is j                int l = Math.max(0, j - k);                int r = Math.min(9, j + k);                 // Perform Range update                next[l] += dp[j];                next[r + 1] -= dp[j];            }             // Prefix sum to find actual count            // of i-digit numbers ending with j            for (int j = 1; j <= 9; j++)                next[j] += next[j - 1];             // Update dp[]            for (int j = 0; j < 10; j++) {                dp[j] = next[j];                next[j] = 0;            }        }         // Stores the final answer        long count = 0;        for (int i = 0; i <= 9; i++)            count += dp[i];         // Return the final answer        return count;    }     // Driver Code    public static void main(String[] args)    {        int n = 2, k = 1;        System.out.println(getCount(n, k));    }}

Python3

 # Python3 program to implement# the above approach # Function to return the count# of such numbersdef getCount(n, K):     # For 1-digit numbers, the count    # is 10 irrespective of K    if(n == 1):        return 10     # dp[j] stores the number    # of such i-digit numbers    # ending with j    dp =  * 11     # Stores the results of length i    next =  * 11     # Initialize count for    # 1-digit numbers    for i in range(1, 9 + 1):        dp[i] = 1     # Compute values for count of    # digits greater than 1    for i in range(2, n + 1):        for j in range(9 + 1):             # Find the range of allowed            # numbers if last digit is j            l = max(0, j - k)            r = min(9, j + k)             # Perform Range update            next[l] += dp[j]            next[r + 1] -= dp[j]         # Prefix sum to find actual count        # of i-digit numbers ending with j        for j in range(1, 9 + 1):            next[j] += next[j - 1]         # Update dp[]        for j in range(10):            dp[j] = next[j]            next[j] = 0     # Stores the final answer    count = 0    for i in range(9 + 1):        count += dp[i]     # Return the final answer    return count # Driver codeif __name__ == '__main__':     n = 2    k = 1         print(getCount(n, k)) # This code is contributed by Shivam Singh

C#

 // C# program to implement// the above approachusing System; class GFG{ // Function to return the count// of such numberspublic static long getCount(int n, int k){         // For 1-digit numbers, the count    // is 10 irrespective of K    if (n == 1)        return 10;     // dp[j] stores the number    // of such i-digit numbers    // ending with j    long []dp = new long;     // Stores the results of length i    long []next = new long;     // Initialize count for    // 1-digit numbers    for(int i = 1; i <= 9; i++)        dp[i] = 1;     // Compute values for count of    // digits greater than 1    for(int i = 2; i <= n; i++)    {        for(int j = 0; j <= 9; j++)        {                         // Find the range of allowed            // numbers if last digit is j            int l = Math.Max(0, j - k);            int r = Math.Min(9, j + k);             // Perform Range update            next[l] += dp[j];            next[r + 1] -= dp[j];        }         // Prefix sum to find actual count        // of i-digit numbers ending with j        for(int j = 1; j <= 9; j++)            next[j] += next[j - 1];         // Update []dp        for(int j = 0; j < 10; j++)        {            dp[j] = next[j];            next[j] = 0;        }    }     // Stores the readonly answer    long count = 0;    for(int i = 0; i <= 9; i++)        count += dp[i];     // Return the readonly answer    return count;} // Driver Codepublic static void Main(String[] args){    int n = 2, k = 1;    Console.WriteLine(getCount(n, k));}} // This code is contributed by amal kumar choubey

Javascript


Output:
26

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

My Personal Notes arrow_drop_up