给定一个正整数N ,任务是构造在字典上大小最大的数组(2 * N – 1) ,该数组由前N个自然数组成,以使每个元素(除1之外)出现两次,并且X的重复在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
方法:可以使用回溯解决问题。想法是根据给定条件生成所有可能的排列,并打印满足给定条件的排列。请按照以下步骤解决问题:
- 在每个索引处初始化一个大小为(2 * N – 1) 0 s的数组ans [] ,并初始化一个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)
# Prthe 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.
输出:
4 2 3 2 4 3 1
时间复杂度: O(N!)
辅助空间: O(N)