📌  相关文章
📜  从前N个自然数开始,按字典顺序的最大数组,以使每个重复出现的距离都等于其前一次出现的值

📅  最后修改于: 2021-04-17 17:25:20             🧑  作者: Mango

给定一个正整数N ,任务是构造在字典上大小最大的数组(2 * N – 1) ,该数组由前N个自然数组成,以使每个元素(除1之外)出现两次,并且X的重复在X中正好相距X距离。构造数组。

例子:

方法:可以使用回溯解决问题。想法是根据给定条件生成所有可能的排列,并打印满足给定条件的排列。请按照以下步骤解决问题:

  • 在每个索引处初始化一个大小为(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)