Count of Arrays of size N having absolute difference between adjacent elements at most 1
Given a positive integer M and an array arr[] of size N and a few integers are missing in the array represented as -1, the task is to find the count of distinct arrays after replacing all -1 with the elements over the range [1, M] such that the absolute difference between any pair of adjacent elements is at most 1.
Examples:
Input: arr[] = {2, -1, 2}, M = 5
Output: 3
Explanation:
The arrays that follow the given conditions are {2, 1, 2}, {2, 2, 2} and {2, 3, 2}.Input: arr[] = {4, -1, 2, 1, -1, -1}, M = 10
Output: 5
Approach: The given problem can be solved using Dynamic Programming based on the following observations:
- Consider a 2D array, say dp[][] where dp[i][j] represents the count of valid arrays of length i+1 having their last element as j.
- Since the absolute difference between any adjacent elements must be at most 1, so for any integer j, the valid adjacent integer can be j-1, j, and j+1. Therefore, any state dp[i][j] can be calculated using the following relation:
dp[ i ][ j ] = dp[ i-1 ][ j ] + dp[ i-1 ][ j-1 ] + dp[ i-1 ][ j+1 ]
- In cases where arr[i] = -1, calculate dp[i][j] = (dp[i-1][j] + dp[i-1][j-1] + dp[i-1][j+1]) for all values of j in the range [1, M].
- In cases where arr[i] != -1, calculate dp[i][j] = (dp[i-1][j] + dp[i-1][j-1] + dp[i-1][j+1]) for j = arr[i].
- Note that in cases where arr[0] = -1, all values in range [1, M] are reachable as the 1st array element, therefore initialize dp[0][j] = 1 for all j in the range [1, M] otherwise initialize dp[0][arr[0]] = 1.
- The required answer will be the sum of all values of dp[N – 1][j] for all j in the range [1, M].
Below is the implementation of the above approach:
C++
// C++ program of the above approach #include <bits/stdc++.h> using namespace std; // Function to find the count of possible // arrays such that the absolute difference // between any adjacent elements is atmost 1 int countArray( int arr[], int N, int M) { // Stores the dp states where dp[i][j] // represents count of arrays of length // i+1 having their last element as j int dp[N][M + 2]; memset (dp, 0, sizeof dp); // Case where 1st array element is missing if (arr[0] == -1) { // All integers in range [1, M] // are reachable for ( int j = 1; j <= M; j++) { dp[0][j] = 1; } } else { // Only reachable integer is arr[0] dp[0][arr[0]] = 1; } // Iterate through all values of i for ( int i = 1; i < N; i++) { // If arr[i] is not missing if (arr[i] != -1) { // Only valid value of j is arr[i] int j = arr[i]; dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]; } // If arr[i] is missing if (arr[i] == -1) { // Iterate through all possible // values of j in range [1, M] for ( int j = 1; j <= M; j++) { dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]; } } } // Stores the count of valid arrays int arrCount = 0; // Calculate the total count of // valid arrays for ( int j = 1; j <= M; j++) { arrCount += dp[N - 1][j]; } // Return answer return arrCount; } // Driver Code int main() { int arr[] = { 4, -1, 2, 1, -1, -1 }; int N = sizeof (arr) / sizeof (arr[0]); int M = 10; // Function Call cout << countArray(arr, N, M); return 0; } |
Java
// Java program of the above approach class GFG { // Function to find the count of possible // arrays such that the absolute difference // between any adjacent elements is atmost 1 public static int countArray( int arr[], int N, int M) { // Stores the dp states where dp[i][j] // represents count of arrays of length // i+1 having their last element as j int [][] dp = new int [N][M + 2 ]; for ( int i = 0 ; i < N; i++) { for ( int j = 0 ; j < M + 2 ; j++) { dp[i][j] = 0 ; } } // Case where 1st array element is missing if (arr[ 0 ] == - 1 ) { // All integers in range [1, M] // are reachable for ( int j = 1 ; j <= M; j++) { dp[ 0 ][j] = 1 ; } } else { // Only reachable integer is arr[0] dp[ 0 ][arr[ 0 ]] = 1 ; } // Iterate through all values of i for ( int i = 1 ; i < N; i++) { // If arr[i] is not missing if (arr[i] != - 1 ) { // Only valid value of j is arr[i] int j = arr[i]; dp[i][j] += dp[i - 1 ][j - 1 ] + dp[i - 1 ][j] + dp[i - 1 ][j + 1 ]; } // If arr[i] is missing if (arr[i] == - 1 ) { // Iterate through all possible // values of j in range [1, M] for ( int j = 1 ; j <= M; j++) { dp[i][j] += dp[i - 1 ][j - 1 ] + dp[i - 1 ][j] + dp[i - 1 ][j + 1 ]; } } } // Stores the count of valid arrays int arrCount = 0 ; // Calculate the total count of // valid arrays for ( int j = 1 ; j <= M; j++) { arrCount += dp[N - 1 ][j]; } // Return answer return arrCount; } // Driver Code public static void main(String args[]) { int arr[] = { 4 , - 1 , 2 , 1 , - 1 , - 1 }; int N = arr.length; int M = 10 ; // Function Call System.out.println(countArray(arr, N, M)); } } // This code is contributed by _saurabh_jaiswal. |
Python3
# Python 3 program of the above approach # Function to find the count of possible # arrays such that the absolute difference # between any adjacent elements is atmost 1 def countArray(arr, N, M): # Stores the dp states where dp[i][j] # represents count of arrays of length # i+1 having their last element as j dp = [[ 0 for i in range (M + 2 )] for j in range (N)] # Case where 1st array element is missing if (arr[ 0 ] = = - 1 ): # All integers in range [1, M] # are reachable for j in range ( 1 ,M + 1 , 1 ): dp[ 0 ][j] = 1 else : # Only reachable integer is arr[0] dp[ 0 ][arr[ 0 ]] = 1 # Iterate through all values of i for i in range ( 1 , N, 1 ): # If arr[i] is not missing if (arr[i] ! = - 1 ): # Only valid value of j is arr[i] j = arr[i] dp[i][j] + = dp[i - 1 ][j - 1 ] + dp[i - 1 ][j] + dp[i - 1 ][j + 1 ] # If arr[i] is missing if (arr[i] = = - 1 ): # Iterate through all possible # values of j in range [1, M] for j in range ( 1 ,M + 1 , 1 ): dp[i][j] + = dp[i - 1 ][j - 1 ] + dp[i - 1 ][j] + dp[i - 1 ][j + 1 ] # Stores the count of valid arrays arrCount = 0 # Calculate the total count of # valid arrays for j in range ( 1 ,M + 1 , 1 ): arrCount + = dp[N - 1 ][j] # Return answer return arrCount # Driver Code if __name__ = = '__main__' : arr = [ 4 , - 1 , 2 , 1 , - 1 , - 1 ] N = len (arr) M = 10 # Function Call print (countArray(arr, N, M)) # This code is contributed by SURENDRA_GANGWAR. |
C#
// C# program of the above approach using System; public class GFG { // Function to find the count of possible // arrays such that the absolute difference // between any adjacent elements is atmost 1 public static int countArray( int []arr, int N, int M) { // Stores the dp states where dp[i][j] // represents count of arrays of length // i+1 having their last element as j int [,] dp = new int [N, M + 2]; for ( int i = 0; i < N; i++) { for ( int j = 0; j < M + 2; j++) { dp[i, j] = 0; } } // Case where 1st array element is missing if (arr[0] == -1) { // All integers in range [1, M] // are reachable for ( int j = 1; j <= M; j++) { dp[0, j] = 1; } } else { // Only reachable integer is arr[0] dp[0, arr[0]] = 1; } // Iterate through all values of i for ( int i = 1; i < N; i++) { // If arr[i] is not missing if (arr[i] != -1) { // Only valid value of j is arr[i] int j = arr[i]; dp[i, j] += dp[i - 1, j - 1] + dp[i - 1, j] + dp[i - 1, j + 1]; } // If arr[i] is missing if (arr[i] == -1) { // Iterate through all possible // values of j in range [1, M] for ( int j = 1; j <= M; j++) { dp[i, j] += dp[i - 1, j - 1] + dp[i - 1, j] + dp[i - 1, j + 1]; } } } // Stores the count of valid arrays int arrCount = 0; // Calculate the total count of // valid arrays for ( int j = 1; j <= M; j++) { arrCount += dp[N - 1, j]; } // Return answer return arrCount; } // Driver Code public static void Main(String[] args) { int []arr = { 4, -1, 2, 1, -1, -1 }; int N = arr.Length; int M = 10; // Function Call Console.WriteLine(countArray(arr, N, M)); } } // This code is contributed by AnkThon. |
Javascript
<script> // JavaScript Program to implement // the above approach // Function to find the count of possible // arrays such that the absolute difference // between any adjacent elements is atmost 1 function countArray(arr, N, M) { // Stores the dp states where dp[i][j] // represents count of arrays of length // i+1 having their last element as j let dp = new Array(N); // Loop to create 2D array using 1D array for (let i = 0; i < dp.length; i++) { dp[i] = new Array(M + 2).fill(0); } // Case where 1st array element is missing if (arr[0] == -1) { // All integers in range [1, M] // are reachable for (let j = 1; j <= M; j++) { dp[0][j] = 1; } } else { // Only reachable integer is arr[0] dp[0][arr[0]] = 1; } // Iterate through all values of i for (let i = 1; i < N; i++) { // If arr[i] is not missing if (arr[i] != -1) { // Only valid value of j is arr[i] let j = arr[i]; dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]; } // If arr[i] is missing if (arr[i] == -1) { // Iterate through all possible // values of j in range [1, M] for (let j = 1; j <= M; j++) { dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]; } } } // Stores the count of valid arrays let arrCount = 0; // Calculate the total count of // valid arrays for (let j = 1; j <= M; j++) { arrCount += dp[N - 1][j]; } // Return answer return arrCount; } // Driver Code let arr = [4, -1, 2, 1, -1, -1]; let N = arr.length; let M = 10; // Function Call document.write(countArray(arr, N, M)); // This code is contributed by Potta Lokesh </script> |
5
Time Complexity: O(N*M)
Auxiliary Space: O(N*M)