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++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the count // of required arrangements int countWays( int n)
{ // Create a vector
vector< int > a;
int i = 1;
// Store numbers from 1 to n
while (i <= n)
a.push_back(i++);
// To store the count of ways
int ways = 0;
// Generate all the permutations
// using next_permutation in STL
do {
// Initialize flag to true if first
// element is 1 else false
bool flag = (a[0] == 1);
// Checking if the current permutation
// satisfies the given conditions
for ( int i = 1; i < n; i++) {
// If the current permutation is invalid
// then set the flag to false
if ( abs (a[i] - a[i - 1]) > 2)
flag = 0;
}
// If valid arrangement
if (flag)
ways++;
// Generate the next permutation
} while (next_permutation(a.begin(), a.end()));
return ways;
} // Driver code int main()
{ int n = 6;
cout << countWays(n);
return 0;
} |
// Java implementation of the // above approach import java.util.*;
class GFG{
// Function to return the count // of required arrangements static int countWays( int n)
{ // Create a vector
Vector<Integer> a =
new Vector<>();
int i = 1 ;
// Store numbers from
// 1 to n
while (i <= n)
a.add(i++);
// To store the count
// of ways
int ways = 0 ;
// Generate all the permutations
// using next_permutation in STL
do
{
// Initialize flag to true
// if first element is 1
// else false
boolean flag = (a.get( 0 ) == 1 );
// Checking if the current
// permutation satisfies the
// given conditions
for ( int j = 1 ; j < n; j++)
{
// If the current permutation
// is invalid then set the
// flag to false
if (Math.abs(a.get(j) -
a.get(j - 1 )) > 2 )
flag = false ;
}
// If valid arrangement
if (flag)
ways++;
// Generate the next permutation
} 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 ;
} // Driver code public static void main(String[] args)
{ int n = 6 ;
System.out.print(countWays(n));
} } // This code is contributed by shikhasingrajput |
# Python3 implementation of the approach from itertools import permutations
# Function to return the count # of required arrangements def countWays(n):
# Create a vector
a = []
i = 1
# Store numbers from 1 to n
while (i < = n):
a.append(i)
i + = 1
# To store the count of ways
ways = 0
# Generate the all permutation
for per in list (permutations(a)):
# Initialize flag to true if first
# element is 1 else false
flag = 1 if (per[ 0 ] = = 1 ) else 0
# Checking if the current permutation
# satisfies the given conditions
for i in range ( 1 , n):
# If the current permutation is invalid
# then set the flag to false
if ( abs (per[i] - per[i - 1 ]) > 2 ):
flag = 0
# If valid arrangement
if (flag):
ways + = 1
return ways
# Driver code n = 6
print (countWays(n))
# This code is contributed by shivanisinghss2110 |
// C# implementation of the // above approach using System;
using System.Collections.Generic;
class GFG{
// Function to return the count // of required arrangements static int countWays( int n)
{ // Create a vector
List< int > a =
new List< int >();
int i = 1;
// Store numbers from
// 1 to n
while (i <= n)
a.Add(i++);
// To store the count
// of ways
int ways = 0;
// Generate all the
// permutations using
// next_permutation in STL
do
{
// Initialize flag to true
// if first element is 1
// else false
bool flag = (a[0] == 1);
// Checking if the current
// permutation satisfies the
// given conditions
for ( int j = 1; j < n; j++)
{
// If the current permutation
// is invalid then set the
// flag to false
if (Math.Abs(a[j] -
a[j - 1]) > 2)
flag = false ;
}
// If valid arrangement
if (flag)
ways++;
// Generate the next
// permutation
} 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 ;
} // Driver code public static void Main(String[] args)
{ int n = 6;
Console.Write(countWays(n));
} } // This code is contributed by Rajput-Ji |
<script> // Javascript implementation of the // above approach // Function to return the count // of required arrangements function countWays(n)
{ // Create a vector
let a =[];
let i = 1;
// Store numbers from
// 1 to n
while (i <= n)
a.push(i++);
// To store the count
// of ways
let ways = 0;
// Generate all the permutations
// using next_permutation in STL
do
{
// Initialize flag to true
// if first element is 1
// else false
let flag = (a[0] == 1);
// Checking if the current
// permutation satisfies the
// given conditions
for (let j = 1; j < n; j++)
{
// If the current permutation
// is invalid then set the
// flag to false
if (Math.abs(a[j] -
a[j - 1]) > 2)
flag = false ;
}
// If valid arrangement
if (flag)
ways++;
// Generate the next permutation
} 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 ;
} // Driver code let n = 6; document.write(countWays(n)); // This code is contributed by patel2127 </script> |
9
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++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the count // of required arrangements int countWays( int n)
{ // Create the dp array
int dp[n + 1];
// Initialize the base cases
// as explained above
dp[0] = 0;
dp[1] = 1;
// (12) as the only possibility
dp[2] = 1;
// Generate answer for greater values
for ( int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
// dp[n] contains the desired answer
return dp[n];
} // Driver code int main()
{ int n = 6;
cout << countWays(n);
return 0;
} |
// Java implementation of the approach class GFG
{ // Function to return the count // of required arrangements static int countWays( int n)
{ // Create the dp array
int []dp = new int [n + 1 ];
// Initialize the base cases
// as explained above
dp[ 0 ] = 0 ;
dp[ 1 ] = 1 ;
// (12) as the only possibility
dp[ 2 ] = 1 ;
// Generate answer for greater values
for ( int i = 3 ; i <= n; i++)
{
dp[i] = dp[i - 1 ] + dp[i - 3 ] + 1 ;
}
// dp[n] contains the desired answer
return dp[n];
} // Driver code public static void main(String args[])
{ int n = 6 ;
System.out.println(countWays(n));
} } // This code is contributed by 29AjayKumar |
# Python implementation of the approach # Function to return the count # of required arrangements def countWays(n):
# Create the dp array
dp = [ 0 for i in range (n + 1 )]
# Initialize the base cases
# as explained above
dp[ 0 ] = 0
dp[ 1 ] = 1
# (12) as the only possibility
dp[ 2 ] = 1
# Generate answer for greater values
for i in range ( 3 , n + 1 ):
dp[i] = dp[i - 1 ] + dp[i - 3 ] + 1
# dp[n] contains the desired answer
return dp[n]
# Driver code n = 6
print (countWays(n))
# This code is contributed by Mohit Kumar |
// C# implementation of the approach using System;
class GFG
{ // Function to return the count // of required arrangements static int countWays( int n)
{ // Create the dp array
int []dp = new int [n + 1];
// Initialize the base cases
// as explained above
dp[0] = 0;
dp[1] = 1;
// (12) as the only possibility
dp[2] = 1;
// Generate answer for greater values
for ( int i = 3; i <= n; i++)
{
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
// dp[n] contains the desired answer
return dp[n];
} // Driver code public static void Main()
{ int n = 6;
Console.WriteLine(countWays(n));
} } // This code is contributed by Code@Mech. |
<script> // Function to return the count // of required arrangements function countWays( n)
{ // Create the dp array
let dp = new Array (n + 1);
// Initialize the base cases
// as explained above
dp[0] = 0;
dp[1] = 1;
// (12) as the only possibility
dp[2] = 1;
// Generate answer for greater values
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 3] + 1;
}
// dp[n] contains the desired answer
return dp[n];
} // Driver code let n = 6;
document.write(countWays(n));
// This code is contributed by shivanisinghss2110
</script> |
9
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++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the count // of required arrangements int countWays( int n)
{ // Initialize the base cases
// as explained above
int prev1 =0;
int prev2 =1;
int prev3 =1;
// to store current value
int curr;
// Generate answer for greater values
for ( int i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
// assigning values for further iterations
prev1 = prev2;
prev2=prev3;
prev3=curr;
}
// curr contains the desired answer
return curr;
} // Driver code int main()
{ int n = 6;
// function call
cout << countWays(n);
return 0;
} |
# Python implementation of the # aforementioned approach def countWays(n):
# Initializing 3 variables
# prev1 = 0
# prev2 = 1
# prev3 = 1
prev1, prev2, prev3 = 0 , 1 , 1
# Running a loop from 3 to n
for i in range ( 3 , n + 1 ):
# using variable curr to store
# the recent value
curr = prev3 + prev1 + 1
# assigning values for further iterations
prev1 = prev2
prev2 = prev3
prev3 = curr
return curr
# Driver Code n = 6
print (countWays(n))
|
// Function to return the count // of required arrangements function countWays(n) {
// Initialize the base cases
// as explained above
let prev1 = 0;
let prev2 = 1;
let prev3 = 1;
// to store current value
let curr;
// Generate answer for greater values
for (let i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
// assigning values for further iterations
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
// curr contains the desired answer
return curr;
} // Driver code let n = 6; // function call console.log(countWays(n)); |
// Java implementation of the approach import java.util.*;
class Main {
// Function to return the count
// of required arrangements
public static int countWays( int n)
{
// Initialize the base cases
// as explained above
int prev1 = 0 ;
int prev2 = 1 ;
int prev3 = 1 ;
// to store current value
int curr = 0 ;
// Generate answer for greater values
for ( int i = 3 ; i <= n; i++) {
curr = prev3 + prev1 + 1 ;
// assigning values for further iterations
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
// curr contains the desired answer
return curr;
}
// Driver code
public static void main(String[] args)
{
int N = 6 ;
System.out.print(countWays(N));
}
} |
using System;
public class MainClass {
// Driver Code
public static void Main()
{
int n = 6;
// Initialize the base cases
// as explained above
int prev1 = 0;
int prev2 = 1;
int prev3 = 1;
int curr = 0;
// Generate answer for greater values
for ( int i = 3; i <= n; i++) {
curr = prev3 + prev1 + 1;
// Assigning values for
// further iterations
prev1 = prev2;
prev2 = prev3;
prev3 = curr;
}
// curr contains desired answer
Console.WriteLine(curr);
}
} |
Output
9
Time Complexity: O(N)
Space Complexity: O(1)