给定一个正整数N,则任务是构建字典顺序最大尺寸(2 * N – 1)的阵列,其包括第一N的自然数,使得每个元件除1出现两次并且X的重复正是X的距离间隔在构造的数组。
例子:
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
方法:这个问题可以使用回溯法解决。这个想法是根据给定条件生成所有可能的排列并打印满足给定条件的排列。请按照以下步骤解决问题:
- 初始化一个数组,比如ans[] ,每个索引的大小为(2*N – 1) 0 s 和一个 HashMap 来存储分配给构造数组的所有元素。
- 定义一个函数constructedArray(i, N)以通过执行以下步骤生成结果数组:
- 如果i 的值为(2*N – 1) ,则生成可能的排列之一。因此,返回true 。
- 否则,如果当前索引处的值已经分配,则递归调用下一次迭代constructArray(i+1, N) 。
- 否则,执行以下操作:
- 放置从范围内的每个未访问号码[1,N]:由N开始。
- 如果在上述步骤中选择的值不会导致数组的可能组合,则从数组中删除当前值并通过分配范围中的其他元素来尝试其他可能的组合。
- 如果没有获得可能的组合,则返回false 。
- 完成上述步骤后,打印得到的数组ans[] 。
下面是上述方法的实现:
C++
// C++14 program to implement
// the above approach
#include
using namespace std;
const int N = 4;
// Stores the required sequence
vector ans(2 * N - 1, 0);
// Stores the visited and unvisited values
set 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
// 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 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
# 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#
// 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 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();
// Function Call
constructArray(0, N);
// Print the resultant array
foreach (int X in ans)
Console.Write(X + " ");
}
}
// This code is contributed by code_hunt.
Javascript
输出:
4 2 3 2 4 3 1
时间复杂度: O(N!)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。