Given a positive integer N, the task is to construct the lexicographically largest array of size (2 * N – 1) comprising of first N natural numbers such that each element occurs twice except 1 and the repetition of X is exactly X distance apart in the constructed array.
Examples:
Input: N = 4
Output: 4 2 3 2 4 3 1
Explanation:
For the generated array {4, 2, 3, 2, 4, 3, 1} each duplicate element(say X) is at distance X.Input: N = 5
Output: 5 3 1 4 3 5 2 4 2
Approach: The problem can be solved using Backtracking. The idea is to generate all possible permutations as per the given condition and print the one that satisfies the given conditions. Follow the steps below to solve the problem:
- Initialize an array, say ans[], of size (2*N – 1) 0s at every index and a HashMap to store all the elements assigned to the constructed array.
- Define a function constructedArray(i, N) to generate the resultant array by performing following steps:
- If the value of i is (2*N – 1), then one of the possible permutations is generated. Therefore, return true.
- Otherwise, if the value at the current index is already assigned, then recursively call for the next iteration constructArray(i+1, N).
- Otherwise, perform the following:
- Place every unvisited number from the range[1, N] starting from N.
- If the value chosen in the above step doesn’t lead to a possible combination of the array, then remove the current value from the array and try other possible combinations by assigning other elements from the range.
- If no possible combination is obtained, then return false.
- After completing the above steps, print the array ans[] as obtained.
Below is the implementation of the above approach:
// C++14 program to implement // the above approach #include <bits/stdc++.h> using namespace std;
const int N = 4;
// Stores the required sequence vector< int > ans(2 * N - 1, 0);
// Stores the visited and unvisited values set< int > visited;
// Function to construct the array // according to the given conditions bool constructArray( int i)
{ // Base Case
if (i == ans.size()) {
return true ;
}
// If a value is already assigned
// at current index, then recursively
// call for the next index
if (ans[i] != 0)
return constructArray(i + 1);
else {
// Iterate over the range[N, 1]
for ( int val = N; val >= 1; val--) {
// If the current value is
// already visited, continue
if (visited.find(val) != visited.end())
continue ;
// Otherwise, mark this value as
// visited and set ans[i] = val
visited.insert(val);
ans[i] = val;
// If val is equal to 1, then
// recursively call for the
// next index
if (val == 1) {
bool found = constructArray(i + 1);
// If solution is found,
// then return true
if (found)
return true ;
}
// For all other values, assign
// ans[i + val] to val if the
// i + val < ans.length
else if (i + val < ans.size()
&& ans[i + val] == 0) {
ans[val + i] = val;
// Recursively call for
// next index to check if
// solution can be found
bool found = constructArray(i + 1);
// If solution is found then
// return true
if (found)
return true ;
// BackTracking step
ans[i + val] = 0;
}
// BackTracking step
ans[i] = 0;
visited.erase(val);
}
}
// In all other cases, return false
return false ;
} // Driver code int main()
{ // Function Call
constructArray(0);
// Print the resultant array
for ( int X : ans)
cout << X << " " ;
return 0;
} // This code is contributed by kingash. |
// Java program for the above approach import java.io.*;
import java.util.*;
class GFG {
// Stores the required sequence
static int ans[];
// Stores the visited and unvisited values
static HashSet<Integer> visited;
// Function to construct the array
// according to the given conditions
public static boolean
constructArray( int i, int N)
{
// Base Case
if (i == ans.length) {
return true ;
}
// If a value is already assigned
// at current index, then recursively
// call for the next index
if (ans[i] != 0 )
return constructArray(i + 1 , N);
else {
// Iterate over the range[N, 1]
for ( int val = N; val >= 1 ; val--) {
// If the current value is
// already visited, continue
if (visited.contains(val))
continue ;
// Otherwise, mark this value as
// visited and set ans[i] = val
visited.add(val);
ans[i] = val;
// If val is equal to 1, then
// recursively call for the
// next index
if (val == 1 ) {
boolean found
= constructArray(i + 1 , N);
// If solution is found,
// then return true
if (found)
return true ;
}
// For all other values, assign
// ans[i + val] to val if the
// i + val < ans.length
else if (i + val < ans.length
&& ans[i + val] == 0 ) {
ans[val + i] = val;
// Recursively call for
// next index to check if
// solution can be found
boolean found
= constructArray(i + 1 , N);
// If solution is found then
// return true
if (found)
return true ;
// BackTracking step
ans[i + val] = 0 ;
}
// BackTracking step
ans[i] = 0 ;
visited.remove(val);
}
}
// In all other cases, return false
return false ;
}
// Driver Code
public static void main(String[] args)
{
int N = 4 ;
ans = new int [ 2 * N - 1 ];
visited = new HashSet<>();
// Function Call
constructArray( 0 , N);
// Print the resultant array
for ( int X : ans)
System.out.print(X + " " );
}
} |
# Python3 program for the above approach # Function to construct the array # according to the given conditions def constructArray(i, N):
global ans, visited
# Base Case
if (i = = len (ans)):
return True
# If a value is already assigned
# at current index, then recursively
# call for the next index
if (ans[i] ! = 0 ):
return constructArray(i + 1 , N)
else :
# Iterate over the range[N, 1]
for val in range (N, 0 , - 1 ):
# If the current value is
# already visited, continue
if (val in visited):
continue
# Otherwise, mark this value as
# visited and set ans[i] = val
visited[val] = 1
ans[i] = val
# If val is equal to 1, then
# recursively call for the
# next index
if (val = = 1 ):
found = constructArray(i + 1 , N)
# If solution is found,
# then return true
if (found):
return True
# For all other values, assign
# ans[i + val] to val if the
# i + val < ans.length
elif (i + val < len (ans) and ans[i + val] = = 0 ):
ans[val + i] = val
# Recursively call for
# next index to check if
# solution can be found
found = constructArray(i + 1 , N)
# If solution is found then
# return true
if (found):
return True
# BackTracking step
ans[i + val] = 0
# BackTracking step
ans[i] = 0
del visited[val]
# In all other cases, return false
return False
# Driver Code if __name__ = = '__main__' :
N = 4
ans = [ 0 ] * ( 2 * N - 1 )
visited = {}
# Function Call
constructArray( 0 , N)
# Print the resultant array
for x in ans:
print (x,end = " " )
# this code is contributed by mohit kumar 29.
|
// C# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
class GFG{
// Stores the required sequence
static int [] ans;
// Stores the visited and unvisited values
static HashSet< int > visited;
// Function to construct the array
// according to the given conditions
public static bool
constructArray( int i, int N)
{
// Base Case
if (i == ans.Length) {
return true ;
}
// If a value is already assigned
// at current index, then recursively
// call for the next index
if (ans[i] != 0)
return constructArray(i + 1, N);
else {
// Iterate over the range[N, 1]
for ( int val = N; val >= 1; val--) {
// If the current value is
// already visited, continue
if (visited.Contains(val))
continue ;
// Otherwise, mark this value as
// visited and set ans[i] = val
visited.Add(val);
ans[i] = val;
// If val is equal to 1, then
// recursively call for the
// next index
if (val == 1) {
bool found
= constructArray(i + 1, N);
// If solution is found,
// then return true
if (found)
return true ;
}
// For all other values, assign
// ans[i + val] to val if the
// i + val < ans.length
else if (i + val < ans.Length
&& ans[i + val] == 0) {
ans[val + i] = val;
// Recursively call for
// next index to check if
// solution can be found
bool found
= constructArray(i + 1, N);
// If solution is found then
// return true
if (found)
return true ;
// BackTracking step
ans[i + val] = 0;
}
// BackTracking step
ans[i] = 0;
visited.Remove(val);
}
}
// In all other cases, return false
return false ;
}
// Driver Code
static public void Main()
{
int N = 4;
ans = new int [2 * N - 1];
visited = new HashSet< int >();
// Function Call
constructArray(0, N);
// Print the resultant array
foreach ( int X in ans)
Console.Write(X + " " );
}
} // This code is contributed by code_hunt. |
<script> // JavaScript program for the above approach
// Stores the required sequence
var ans = [];
// Stores the visited and unvisited values
var visited = [];
// Function to construct the array
// according to the given conditions
function constructArray(i, N) {
// Base Case
if (i === ans.length) {
return true ;
}
// If a value is already assigned
// at current index, then recursively
// call for the next index
if (ans[i] !== 0) return constructArray(i + 1, N);
else {
// Iterate over the range[N, 1]
for ( var val = N; val >= 1; val--) {
// If the current value is
// already visited, continue
if (visited.includes(val)) continue ;
// Otherwise, mark this value as
// visited and set ans[i] = val
visited.push(val);
ans[i] = val;
// If val is equal to 1, then
// recursively call for the
// next index
if (val === 1) {
var found = constructArray(i + 1, N);
// If solution is found,
// then return true
if (found) return true ;
}
// For all other values, assign
// ans[i + val] to val if the
// i + val < ans.length
else if (i + val < ans.length && ans[i + val] === 0) {
ans[val + i] = val;
// Recursively call for
// next index to check if
// solution can be found
var found = constructArray(i + 1, N);
// If solution is found then
// return true
if (found) return true ;
// BackTracking step
ans[i + val] = 0;
}
// BackTracking step
ans[i] = 0;
var index = visited.indexOf(val);
if (index !== -1) {
visited.splice(index, 1);
}
}
}
// In all other cases, return false
return false ;
}
// Driver Code
var N = 4;
ans = new Array(2 * N - 1).fill(0);
visited = [];
// Function Call
constructArray(0, N);
// Print the resultant array
for (const X of ans) {
document.write(X + " " );
}
</script>
|
4 2 3 2 4 3 1
Time Complexity: O(N!)
Auxiliary Space: O(N)