Number of ways to form an array with distinct adjacent elements
Given three integers N, M and X, the task is to find the number of ways to form an array, such that all consecutive numbers of the array are distinct, and the value at any index of the array from 2 to N – 1(Considering 1 based indexing) lies between 1 and M, while the value at index 1 is X and the value at index N is 1.
Note: Value of X lies between 1 and M.
Examples:
Input: N = 4, M = 3, X = 2
Output: 3
The following arrays are possible:
1) 2, 1, 2, 1
2) 2, 1, 3, 1
3) 2, 3, 2, 1
Input: N = 2, M = 3, X = 2
Output: 1
The only possible array is: 2, 1
Approach: The problem can be solved using Dynamic Programming. Let, f(i) represent the number of ways to form the array till the ith index, such that every consecutive element of the array is distinct. Let f(i, One) represent the number of ways to form the array till the i-th index such that every consecutive element of the array is distinct and arri = 1.
Similarly, let f(i, Non-One) represent the number of ways to form the array till the ith index, such that every consecutive element of the array is distinct and arri is not equal to 1.
The following recurrence is formed:
f(i, Non-One) = f(i - 1, One) * (M - 1) + f(i - 1, Non-One) * (M - 2)
which means that the number of ways to form the array till the ith index with arrayi not equal to 1 is formed using two cases:
- If the number at arrayi – 1 is 1, then opt one number out of (M – 1) options to place at the ith index, since arrayi is not equal to 1.
- If the number at arrayi – 1 is not 1, then we need to opt one number out of (M – 2) options, since arrayi is not equal to 1 and arrayi ≠arrayi – 1.
Similarly, f(i, One) = f(i – 1, Non-One), since the number of ways to form the array till the ith index with arrayi = 1, is same as number of ways to form the array till the (i – 1)th index with arrayi – 1 ≠1, thus at the ith index there is only one option. At the end the required answer if f(N, One) since arrayN needs to be equal to 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int totalWays( int N, int M, int X)
{
int dp[N + 1][2];
if (X == 1) {
dp[0][0] = 1;
}
else {
dp[0][1] = 0;
}
if (X == 1) {
dp[1][0] = 0;
dp[1][1] = M - 1;
}
else {
dp[1][0] = 1;
dp[1][1] = (M - 2);
}
for ( int i = 2; i < N; i++) {
dp[i][0] = dp[i - 1][1];
dp[i][1] = dp[i - 1][0] * (M - 1) + dp[i - 1][1] * (M - 2);
}
return dp[N - 1][0];
}
int main()
{
int N = 4, M = 3, X = 2;
cout << totalWays(N, M, X) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int totalWays( int N,
int M, int X)
{
int dp[][] = new int [N + 1 ][ 2 ];
if (X == 1 )
{
dp[ 0 ][ 0 ] = 1 ;
}
else
{
dp[ 0 ][ 1 ] = 0 ;
}
if (X == 1 )
{
dp[ 1 ][ 0 ] = 0 ;
dp[ 1 ][ 1 ] = M - 1 ;
}
else
{
dp[ 1 ][ 0 ] = 1 ;
dp[ 1 ][ 1 ] = (M - 2 );
}
for ( int i = 2 ; i < N; i++)
{
dp[i][ 0 ] = dp[i - 1 ][ 1 ];
dp[i][ 1 ] = dp[i - 1 ][ 0 ] * (M - 1 ) +
dp[i - 1 ][ 1 ] * (M - 2 );
}
return dp[N - 1 ][ 0 ];
}
public static void main (String[] args)
{
int N = 4 , M = 3 , X = 2 ;
System.out.println(totalWays(N, M, X));
}
}
|
Python3
def totalWays(N,M,X):
dp = [[ 0 for i in range ( 2 )] for j in range (N + 1 )]
if (X = = 1 ):
dp[ 0 ][ 0 ] = 1
else :
dp[ 0 ][ 1 ] = 0
if (X = = 1 ):
dp[ 1 ][ 0 ] = 0
dp[ 1 ][ 1 ] = M - 1
else :
dp[ 1 ][ 0 ] = 1
dp[ 1 ][ 1 ] = (M - 2 )
for i in range ( 2 ,N):
dp[i][ 0 ] = dp[i - 1 ][ 1 ]
dp[i][ 1 ] = dp[i - 1 ][ 0 ] * (M - 1 ) + dp[i - 1 ][ 1 ] * (M - 2 )
return dp[N - 1 ][ 0 ]
if __name__ = = '__main__' :
N = 4
M = 3
X = 2
print (totalWays(N, M, X))
|
C#
using System;
class GFG
{
static int totalWays( int N,
int M, int X)
{
int [,]dp = new int [N + 1, 2];
if (X == 1)
{
dp[0, 0] = 1;
}
else
{
dp[0, 1] = 0;
}
if (X == 1)
{
dp[1, 0] = 0;
dp[1, 1] = M - 1;
}
else
{
dp[1, 0] = 1;
dp[1, 1] = (M - 2);
}
for ( int i = 2; i < N; i++)
{
dp[i, 0] = dp[i - 1, 1];
dp[i, 1] = dp[i - 1, 0] * (M - 1) +
dp[i - 1, 1] * (M - 2);
}
return dp[N - 1, 0];
}
public static void Main ()
{
int N = 4, M = 3, X = 2;
Console.WriteLine(totalWays(N, M, X));
}
}
|
Javascript
<script>
function totalWays(N, M, X)
{
let dp = new Array(N + 1);
for (let i = 0; i < N + 1; i++)
{
dp[i] = new Array(2);
for (let j = 0; j < 2; j++)
{
dp[i][j] = 0;
}
}
if (X == 1)
{
dp[0][0] = 1;
}
else
{
dp[0][1] = 0;
}
if (X == 1)
{
dp[1][0] = 0;
dp[1][1] = M - 1;
}
else
{
dp[1][0] = 1;
dp[1][1] = (M - 2);
}
for (let i = 2; i < N; i++)
{
dp[i][0] = dp[i - 1][1];
dp[i][1] = dp[i - 1][0] * (M - 1) +
dp[i - 1][1] * (M - 2);
}
return dp[N - 1][0];
}
let N = 4, M = 3, X = 2;
document.write(totalWays(N, M, X));
</script>
|
PHP
<?php
function totalWays( $N , $M , $X )
{
$dp = array ( array ());
if ( $X == 1)
{
$dp [0][0] = 1;
}
else
{
$dp [0][1] = 0;
}
if ( $X == 1)
{
$dp [1][0] = 0;
$dp [1][1] = $M - 1;
}
else
{
$dp [1][0] = 1;
$dp [1][1] = ( $M - 2);
}
for ( $i = 2; $i < $N ; $i ++)
{
$dp [ $i ][0] = $dp [ $i - 1][1];
$dp [ $i ][1] = $dp [ $i - 1][0] *
( $M - 1) +
$dp [ $i - 1][1] *
( $M - 2);
}
return $dp [ $N - 1][0];
}
$N = 4; $M = 3; $X = 2;
echo totalWays( $N , $M , $X );
?>
|
Time Complexity: O(N), where N is the size of the array
Auxiliary Space: O(N), for dp array
Efficient approach : Space optimization O(1)
In previous approach we the current value dp[i] is only depend upon the previous value i.e. dp[i-1]. So to optimize the space we can keep track of previous and current values by the help of three variables prev and curr which will reduce the space complexity from O(N) to O(1).
Implementation Steps:
- Create 2 variables prev and curr to keep track of previous and current values of DP.
- Initialize base case for X == 1.
- Iterate over subproblem using loop and update curr.
- After every iteration update prev and curr for further iterations.
- At last return prev.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int totalWays( int N, int M, int X)
{
int prev, curr;
if (X == 1) {
prev = 1;
} else {
curr = 0;
}
if (X == 1) {
curr = M - 1;
} else {
prev = 1;
curr = M - 2;
}
for ( int i = 2; i < N; i++) {
int temp = prev;
prev = curr;
curr = temp * (M - 1) + curr * (M - 2);
}
return prev;
}
int main()
{
int N = 4, M = 3, X = 2;
cout << totalWays(N, M, X) << endl;
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int totalWays( int N, int M, int X) {
int prev = 0 , curr = 0 ;
if (X == 1 ) {
prev = 1 ;
} else {
curr = M - 1 ;
}
if (X == 1 ) {
curr = M - 1 ;
} else {
prev = 1 ;
curr = M - 2 ;
}
for ( int i = 2 ; i < N; i++) {
int temp = prev;
prev = curr;
curr = temp * (M - 1 ) + curr * (M - 2 );
}
return prev;
}
public static void main(String[] args) {
int N = 4 , M = 3 , X = 2 ;
System.out.println(totalWays(N, M, X));
}
}
|
Python
def totalWays(N, M, X):
if X = = 1 :
prev = 1
else :
curr = 0
if X = = 1 :
curr = M - 1
else :
prev = 1
curr = M - 2
for i in range ( 2 , N):
temp = prev
prev = curr
curr = temp * (M - 1 ) + curr * (M - 2 )
return prev
if __name__ = = "__main__" :
N = 4
M = 3
X = 2
print (totalWays(N, M, X))
|
C#
using System;
namespace ArrayWays
{
class GFG
{
static int TotalWays( int N, int M, int X)
{
int prev = 0, curr = 0;
if (X == 1)
{
prev = 1;
}
else
{
curr = 0;
}
if (X == 1)
{
curr = M - 1;
}
else
{
prev = 1;
curr = M - 2;
}
for ( int i = 2; i < N; i++)
{
int temp = prev;
prev = curr;
curr = temp * (M - 1) + curr * (M - 2);
}
return prev;
}
static void Main( string [] args)
{
int N = 4, M = 3, X = 2;
Console.WriteLine(TotalWays(N, M, X));
}
}
}
|
Javascript
function totalWays(N, M, X) {
let prev, curr;
if (X === 1) {
prev = 1;
} else {
curr = 0;
}
if (X === 1) {
curr = M - 1;
} else {
prev = 1;
curr = M - 2;
}
for (let i = 2; i < N; i++) {
let temp = prev;
prev = curr;
curr = temp * (M - 1) + curr * (M - 2);
}
return prev;
}
const N = 4, M = 3, X = 2;
console.log(totalWays(N, M, X));
|
Output:
3
Time Complexity: O(N), where N is the size of the array
Auxiliary Space: O(1), only use variables
Last Updated :
19 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...