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 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. |
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// 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;
cout << getCount(n, k);
return 0;
} |
// 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));
}
} |
# 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 |
// 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 |
<script> // Javascript program to implement the above approach // Function to find maximum between two numbers function max(num1, num2)
{ return (num1 > num2 ) ? num1 : num2;
} // Function to find minimum between two numbers function min(num1, num2)
{ return (num1 > num2 ) ? num2 : num1;
} // Function to return the count // of such numbers function 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
var dp = Array(11).fill(0);
// Stores the results of length i
var next = Array(11).fill(0);
// Initialize count for
// 1-digit numbers
for ( var i = 1; i <= 9; i++)
dp[i] = 1;
// Compute values for count of
// digits greater than 1
for ( var i = 2; i <= n; i++)
{
for ( var j = 0; j <= 9; j++)
{
// Find the range of allowed
// numbers if last digit is j
var l = Math.max(0, (j - k));
var 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 ( var j = 1; j <= 9; j++)
next[j] += next[j - 1];
// Update dp[]
for ( var j = 0; j < 10; j++)
{
dp[j] = next[j];
next[j] = 0;
}
}
// Stores the final answer
var count = 0;
for ( var i = 0; i <= 9; i++)
count += dp[i];
// Return the final answer
return count;
} // Driver Code var n = 2, k = 1;
document.write( getCount(n, k)); // This code is contributed by chinmoy1997pal. </script> |
26
Time Complexity: O(N)
Auxiliary Space: O(1)