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

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program to implement the above approach
#include <stdio.h>
  
// Function to find maximum between two numbers
int max(int num1, int num2)
{
    return (num1 > num2 ) ? num1 : num2;
}
  
// Function to find minimum between two numbers
int min(int num1, int num2) 
{
    return (num1 > num2 ) ? num2 : num1;
}
  
// Function to return the count
// of such numbers
int 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[11] = {0};
  
    // Stores the results of length i
    int next[11] = {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 Code
int main()
{
    int n = 2, k = 1;
    printf("%d", getCount(n, k));
}
  
// This code is contributed by piyush3010. 

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement
// the above approach
import 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[11];
  
        // Stores the results of length i
        long next[] = new long[11];
  
        // 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));
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
  
# Function to return the count
# of such numbers
def 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 = [0] * 11
  
    # Stores the results of length i
    next = [0] * 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 code
if __name__ == '__main__':
  
    n = 2
    k = 1
      
    print(getCount(n, k))
  
# This code is contributed by Shivam Singh

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
  
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[11];
  
    // Stores the results of length i
    long []next = new long[11];
  
    // 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 Code
public static void Main(String[] args)
{
    int n = 2, k = 1;
    Console.WriteLine(getCount(n, k));
}
}
  
// This code is contributed by amal kumar choubey

chevron_right


Output: 

26

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

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.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.