Count of N-digit numbers with absolute difference of adjacent digits not exceeding K
Last Updated :
29 Nov, 2023
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
The simplest approach is to iterate over all N digit numbers and check for every number if the adjacent digits have an absolute difference less than or equal to K.
Time Complexity: O(10N * N)
Efficient Approach:
To optimize the above approach, we need to use a Dynamic Programming approach along with Range Update
- Initialize a DP[][] array where dp[i][j] stores the count of numbers having i digits and ending with j.
- Iterate the array from 2 to N and check if the last digit was j, then the allowed digits for this place are in the range (max(0, j-k), min(9, j+k)). Perform a range update on this range.
- Now use Prefix Sum to get the actual answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long long getCount( int n, int k)
{
if (n == 1)
return 10;
long long dp[n + 1][11];
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j < 11; j++)
dp[i][j] = 0;
}
for ( int i = 1; i <= 9; i++)
dp[1][i] = 1;
for ( int i = 2; i <= n; i++) {
for ( int j = 0; j <= 9; j++) {
int l = max(0, j - k);
int r = min(9, j + k);
dp[i][l] += dp[i - 1][j];
dp[i][r + 1] -= dp[i - 1][j];
}
for ( int j = 1; j <= 9; j++)
dp[i][j] += dp[i][j - 1];
}
long long count = 0;
for ( int i = 0; i <= 9; i++)
count += dp[n][i];
return count;
}
int main()
{
int N = 2, K = 1;
cout << getCount(N, K);
}
|
Java
import java.util.*;
class GFG {
public static long getCount( int n, int k)
{
if (n == 1 )
return 10 ;
long dp[][]
= new long [n + 1 ][ 11 ];
for ( int i = 1 ; i <= 9 ; i++)
dp[ 1 ][i] = 1 ;
for ( int i = 2 ; i <= n; i++) {
for ( int j = 0 ; j <= 9 ; j++) {
int l = Math.max( 0 , j - k);
int r = Math.min( 9 , j + k);
dp[i][l] += dp[i - 1 ][j];
dp[i][r + 1 ] -= dp[i - 1 ][j];
}
for ( int j = 1 ; j <= 9 ; j++)
dp[i][j] += dp[i][j - 1 ];
}
long count = 0 ;
for ( int i = 0 ; i <= 9 ; i++)
count += dp[n][i];
return count;
}
public static void main(String[] args)
{
int n = 2 , k = 1 ;
System.out.println(getCount(n, k));
}
}
|
Python3
def getCount(n, k):
if n = = 1 :
return 10
dp = [[ 0 for x in range ( 11 )]
for y in range (n + 1 )];
for i in range ( 1 , 10 ):
dp[ 1 ][i] = 1
for i in range ( 2 , n + 1 ):
for j in range ( 0 , 10 ):
l = max ( 0 , j - k)
r = min ( 9 , j + k)
dp[i][l] = dp[i][l] + dp[i - 1 ][j]
dp[i][r + 1 ] = dp[i][r + 1 ] - dp[i - 1 ][j]
for j in range ( 1 , 10 ):
dp[i][j] = dp[i][j] + dp[i][j - 1 ]
count = 0
for i in range ( 0 , 10 ):
count = count + dp[n][i]
return count
n, k = 2 , 1
print (getCount(n, k))
|
C#
using System;
class GFG {
static long getCount( int n, int k)
{
if (n == 1)
return 10;
long [, ] dp = new long [n + 1, 11];
for ( int i = 1; i <= 9; i++)
dp[1, i] = 1;
for ( int i = 2; i <= n; i++) {
for ( int j = 0; j <= 9; j++) {
int l = Math.Max(0, j - k);
int r = Math.Min(9, j + k);
dp[i, l] += dp[i - 1, j];
dp[i, r + 1] -= dp[i - 1, j];
}
for ( int j = 1; j <= 9; j++)
dp[i, j] += dp[i, j - 1];
}
long count = 0;
for ( int i = 0; i <= 9; i++)
count += dp[n, i];
return count;
}
public static void Main()
{
int n = 2, k = 1;
Console.WriteLine(getCount(n, k));
}
}
|
Javascript
<script>
function getCount(n, k)
{
if (n == 1)
return 10;
var dp = new Array(n + 1);
for ( var i = 0; i < dp.length; i++)
dp[i] = Array(11).fill(0);
for (i = 1; i <= 9; i++)
dp[1][i] = 1;
for (i = 2; i <= n; i++)
{
for (j = 0; j <= 9; j++)
{
var l = Math.max(0, j - k);
var r = Math.min(9, j + k);
dp[i][l] += dp[i - 1][j];
dp[i][r + 1] -= dp[i - 1][j];
}
for (j = 1; j <= 9; j++)
dp[i][j] += dp[i][j - 1];
}
var count = 0;
for (i = 0; i <= 9; i++)
count += dp[n][i];
return count;
}
var n = 2, k = 1;
document.write(getCount(n, k));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Efficient approach : Space optimization
In previous approach the current value DP[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D array DP of size 11 and initialize it with 0.
- Set a base case and initialize initialize count for 1 digit number dp[] = 1 .
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- Now Create a 1D array DP2 of size 11 and initialize it with 0 to store the current computation.
- Create a variable count and initialize it with 0 and get the value of count by iterate through Dp.
- At last return and print the count .
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
long long getCount( int n, int k)
{
if (n == 1)
return 10;
long long dp1[11] = {0};
for ( int i = 1; i <= 9; i++)
dp1[i] = 1;
for ( int i = 2; i <= n; i++) {
long long dp2[11] = {0};
for ( int j = 0; j <= 9; j++) {
int l = max(0, j - k);
int r = min(9, j + k);
for ( int d = l; d <= r; d++) {
dp2[d] += dp1[j];
}
}
memcpy (dp1, dp2, sizeof (dp1));
}
long long count = 0;
for ( int i = 0; i <= 9; i++)
count += dp1[i];
return count;
}
int main()
{
int N = 2, K = 1;
cout << getCount(N, K);
}
|
Java
import java.util.Arrays;
class Main
{
static long getCount( int n, int k)
{
if (n == 1 )
return 10 ;
long [] dp1 = new long [ 11 ];
Arrays.fill(dp1, 0 );
for ( int i = 1 ; i <= 9 ; i++)
dp1[i] = 1 ;
for ( int i = 2 ; i <= n; i++) {
long [] dp2 = new long [ 11 ];
Arrays.fill(dp2, 0 );
for ( int j = 0 ; j <= 9 ; j++) {
int l = Math.max( 0 , j - k);
int r = Math.min( 9 , j + k);
for ( int d = l; d <= r; d++) {
dp2[d] += dp1[j];
}
}
System.arraycopy(dp2, 0 , dp1, 0 , dp1.length);
}
long count = 0 ;
for ( int i = 0 ; i <= 9 ; i++)
count += dp1[i];
return count;
}
public static void main(String[] args) {
int N = 2 , K = 1 ;
System.out.println(getCount(N, K));
}
}
|
Python3
def getCount(n, k):
if n = = 1 :
return 10
dp1 = [ 0 ] * 11
for i in range ( 1 , 10 ):
dp1[i] = 1
for i in range ( 2 , n + 1 ):
dp2 = [ 0 ] * 11
for j in range ( 10 ):
l = max ( 0 , j - k)
r = min ( 9 , j + k)
for d in range (l, r + 1 ):
dp2[d] + = dp1[j]
dp1 = dp2[:]
count = 0
for i in range ( 10 ):
count + = dp1[i]
return count
if __name__ = = '__main__' :
N, K = 2 , 1
print (getCount(N, K))
|
C#
using System;
class GFG
{
static long GetCount( int n, int k)
{
if (n == 1)
return 10;
long [] dp1 = new long [11];
for ( int i = 1; i <= 9; i++)
dp1[i] = 1;
for ( int i = 2; i <= n; i++)
{
long [] dp2 = new long [11];
for ( int j = 0; j <= 9; j++)
{
int l = Math.Max(0, j - k);
int r = Math.Min(9, j + k);
for ( int d = l; d <= r; d++)
{
dp2[d] += dp1[j];
}
}
Array.Copy(dp2, dp1, dp1.Length);
}
long count = 0;
for ( int i = 0; i <= 9; i++)
count += dp1[i];
return count;
}
public static void Main()
{
int N = 2, K = 1;
Console.WriteLine(GetCount(N, K));
}
}
|
Javascript
function getCount(n, k) {
if (n == 1) {
return 10;
}
let dp1 = new Array(11).fill(0);
for (let i = 1; i < 10; i++) {
dp1[i] = 1;
}
for (let i = 2; i <= n; i++) {
let dp2 = new Array(11).fill(0);
for (let j = 0; j < 10; j++) {
let l = Math.max(0, j - k);
let r = Math.min(9, j + k);
for (let d = l; d <= r; d++) {
dp2[d] += dp1[j];
}
}
dp1 = dp2.slice();
}
let count = 0;
for (let i = 0; i < 10; i++) {
count += dp1[i];
}
return count;
}
let N = 2, K = 1;
console.log(getCount(N, K));
|
Output
26
Time Complexity: O(N)
Auxiliary Space: O(1) <= O(11)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...