Count number of ways to arrange first N numbers
Last Updated :
09 Apr, 2023
Count number of ways to arrange the first N natural numbers in a line such that the left-most number is always 1 and no two consecutive numbers have an absolute difference greater than 2.
Examples:
Input: N = 4
Output: 4
The only possible arrangements are (1, 2, 3, 4),
(1, 2, 4, 3), (1, 3, 4, 2) and (1, 3, 2, 4).
Input: N = 6
Output: 9
Naive approach: Generate all the permutations and count how many of them satisfy the given conditions.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countWays( int n)
{
vector< int > a;
int i = 1;
while (i <= n)
a.push_back(i++);
int ways = 0;
do {
bool flag = (a[0] == 1);
for ( int i = 1; i < n; i++) {
if ( abs (a[i] - a[i - 1]) > 2)
flag = 0;
}
if (flag)
ways++;
} while (next_permutation(a.begin(), a.end()));
return ways;
}
int main()
{
int n = 6;
cout << countWays(n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int countWays( int n)
{
Vector<Integer> a =
new Vector<>();
int i = 1 ;
while (i <= n)
a.add(i++);
int ways = 0 ;
do
{
boolean flag = (a.get( 0 ) == 1 );
for ( int j = 1 ; j < n; j++)
{
if (Math.abs(a.get(j) -
a.get(j - 1 )) > 2 )
flag = false ;
}
if (flag)
ways++;
} while (next_permutation(a));
return ways;
}
static boolean next_permutation(Vector<Integer> p)
{
for ( int a = p.size() - 2 ;
a >= 0 ; --a)
if (p.get(a) < p.get(a + 1 ))
for ( int b = p.size() - 1 ;; --b)
if (p.get(b) > p.get(a))
{
int t = p.get(a);
p.set(a, p.get(b));
p.set(b, t);
for (++a, b = p.size() - 1 ;
a < b; ++a, --b)
{
t = p.get(a);
p.set(a, p.get(b));
p.set(b, t);
}
return true ;
}
return false ;
}
public static void main(String[] args)
{
int n = 6 ;
System.out.print(countWays(n));
}
}
|
Python3
from itertools import permutations
def countWays(n):
a = []
i = 1
while (i < = n):
a.append(i)
i + = 1
ways = 0
for per in list (permutations(a)):
flag = 1 if (per[ 0 ] = = 1 ) else 0
for i in range ( 1 , n):
if ( abs (per[i] - per[i - 1 ]) > 2 ):
flag = 0
if (flag):
ways + = 1
return ways
n = 6
print (countWays(n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int countWays( int n)
{
List< int > a =
new List< int >();
int i = 1;
while (i <= n)
a.Add(i++);
int ways = 0;
do
{
bool flag = (a[0] == 1);
for ( int j = 1; j < n; j++)
{
if (Math.Abs(a[j] -
a[j - 1]) > 2)
flag = false ;
}
if (flag)
ways++;
} while (next_permutation(a));
return ways;
}
static bool next_permutation(List< int > p)
{
for ( int a = p.Count - 2;
a >= 0; --a)
if (p[a] < p[a + 1])
for ( int b = p.Count - 1;; --b)
if (p[b] > p[a])
{
int t = p[a];
p[a] = p[b];
p[b] = t;
for (++a, b = p.Count - 1;
a < b; ++a, --b)
{
t = p[a];
p[a] = p[b];
p[b] = t;
}
return true ;
}
return false ;
}
public static void Main(String[] args)
{
int n = 6;
Console.Write(countWays(n));
}
}
|
Javascript
<script>
function countWays(n)
{
let a =[];
let i = 1;
while (i <= n)
a.push(i++);
let ways = 0;
do
{
let flag = (a[0] == 1);
for (let j = 1; j < n; j++)
{
if (Math.abs(a[j] -
a[j - 1]) > 2)
flag = false ;
}
if (flag)
ways++;
} while (next_permutation(a));
return ways;
}
function next_permutation(p)
{
for (let a = p.length - 2;a >= 0; --a)
{ if (p[a] < p[a + 1])
{ for (let b = p.length - 1;; --b)
{ if (p[b] > p[a])
{
let t = p[a];
p[a] = p[b];
p[b] = t;
for (++a, b = p.length - 1;
a < b; ++a, --b)
{
t = p[a];
p[a] = p[b];
p[b] = t;
}
return true ;
}
}
}
}
return false ;
}
let n = 6;
document.write(countWays(n));
</script>
|
Efficient approach: This problem can be solved using dynamic programming.
A better linear approach to this problem relies on the following observation. Look for the position of 2. Let a[i] be the number of ways for n = i. There are three cases:
- 12_____ – “2” in the second position.
- 1*2____ – “2” in the third position.
1**2___ – “2” in the fourth position is impossible because only possible way is (1342), which is same as case 3.
1***2__ – “2” in the fifth position is impossible because 1 must be followed by 3, 3 by 5 and 2 needs 4 before it so it becomes 13542, again as case 3.
- 1_(i – 2)terms___2 – “2” in the last position (1357642 and similar)
For each case, the following are the sub-task:
Adding 1 to each term of a[i – 1] i.e. (1__(i – 1) terms__).
As for 1_2_____ there can only be one 1324___(i – 4) terms____ i.e. a[i – 3].
Hence, the recurrence relation will be,
a[i] = a[i – 1] + a[i – 3] + 1
And the base cases will be:
a[0] = 0
a[1] = 1
a[2] = 1
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countWays( int n)
{
int dp[n + 1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for ( int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
return dp[n];
}
int main()
{
int n = 6;
cout << countWays(n);
return 0;
}
|
Java
class GFG
{
static int countWays( int n)
{
int []dp = new int [n + 1 ];
dp[ 0 ] = 0 ;
dp[ 1 ] = 1 ;
dp[ 2 ] = 1 ;
for ( int i = 3 ; i <= n; i++)
{
dp[i] = dp[i - 1 ] + dp[i - 3 ] + 1 ;
}
return dp[n];
}
public static void main(String args[])
{
int n = 6 ;
System.out.println(countWays(n));
}
}
|
Python3
def countWays(n):
dp = [ 0 for i in range (n + 1 )]
dp[ 0 ] = 0
dp[ 1 ] = 1
dp[ 2 ] = 1
for i in range ( 3 , n + 1 ):
dp[i] = dp[i - 1 ] + dp[i - 3 ] + 1
return dp[n]
n = 6
print (countWays(n))
|
C#
using System;
class GFG
{
static int countWays( int n)
{
int []dp = new int [n + 1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for ( int i = 3; i <= n; i++)
{
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
return dp[n];
}
public static void Main()
{
int n = 6;
Console.WriteLine(countWays(n));
}
}
|
Javascript
<script>
function countWays( n)
{
let dp = new Array (n + 1);
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
return dp[n];
}
let n = 6;
document.write(countWays(n));
</script>
|
Time Complexity: O(N)
Space Complexity: O(N)
Efficient approach : Space optimization O(1)
In previous approach the current value dp[i] is depend upon the previous 2 values i.e. dp[i-1] and dp[i-3] so instead of using array of size N we can create 3 variables prev1 , prev2, prev3 to keep track of previous 3 computations.
Implementations Steps :
- Create variables prev1, prev2, prev3 to store previous computations.
- Initialize them with base cases.
- Create a variable curr to store current value.
- Now iterate over subproblems and get the current value from previous values.
- After every iteration update prev1, prev2 and prev3 for further iterations.
- At last return final answer.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int countWays( int n)
{
int prev1 =0;
int prev2 =1;
int prev3 =1;
int curr;
for ( int i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
prev1 = prev2;
prev2=prev3;
prev3=curr;
}
return curr;
}
int main()
{
int n = 6;
cout << countWays(n);
return 0;
}
|
Python3
def countWays(n):
prev1, prev2, prev3 = 0 , 1 , 1
for i in range ( 3 , n + 1 ):
curr = prev3 + prev1 + 1
prev1 = prev2
prev2 = prev3
prev3 = curr
return curr
n = 6
print (countWays(n))
|
Javascript
function countWays(n) {
let prev1 = 0;
let prev2 = 1;
let prev3 = 1;
let curr;
for (let i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
return curr;
}
let n = 6;
console.log(countWays(n));
|
Java
import java.util.*;
class Main {
public static int countWays( int n)
{
int prev1 = 0 ;
int prev2 = 1 ;
int prev3 = 1 ;
int curr = 0 ;
for ( int i = 3 ; i <= n; i++) {
curr = prev3 + prev1 + 1 ;
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
return curr;
}
public static void main(String[] args)
{
int N = 6 ;
System.out.print(countWays(N));
}
}
|
C#
using System;
public class MainClass {
public static void Main()
{
int n = 6;
int prev1 = 0;
int prev2 = 1;
int prev3 = 1;
int curr = 0;
for ( int i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
Console.WriteLine(curr);
}
}
|
Output
9
Time Complexity: O(N)
Space Complexity: O(1)
Share your thoughts in the comments
Please Login to comment...