📌  相关文章
📜  使用Backtracking打印具有重复项的数组的所有可能排列

📅  最后修改于: 2021-05-17 18:32:26             🧑  作者: Mango

给定大小为N的数组nums [] ,任务是打印数组nums []的所有可能的不同排列(包括重复项)。

方法:按照以下步骤解决问题

  1. 遍历数组。
  2. 生成数组的排列。
  3. 设置重复元素之间的选择顺序。
  4. 如果i> 0 && nums [i] == nums [i – 1]:仅在排列中添加了nums [i – 1] ,即访问了[i – 1]时,才在当前排列中添加nums [i]是的
  5. 否则,请继续。
  6. 使用这种方法,打印生成的不同排列。

检查此递归树以了解代码的实现细节。

下面是上述方法的实现:

C++14
// C++ Program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to fill the vector curr
// while maintaining the indices visited
// in the array num
void backtrack(vector& nums,
               vector& curr,
               vector >& ans,
               vector& visited)
{
 
    // If current permutation is complete
    if ((int)curr.size() == (int)nums.size()) {
        ans.push_back(curr);
    }
 
    // Traverse the input vector
    for (int i = 0; i < (int)nums.size();
         i++) {
 
        // If index is already visited
        if (visited[i])
            continue;
 
        // If the numebr is dupicate
        if (i > 0 and nums[i] == nums[i - 1]
            and !visited[i - 1])
            continue;
 
        // Set visited[i] flag as true
        visited[i] = true;
 
        // Push nums[i] to current vector
        curr.push_back(nums[i]);
 
        // Recursive function call
        backtrack(nums, curr,
                  ans, visited);
 
        // Backtrack to the previous
        // state by unsetting visited[i]
        visited[i] = false;
 
        // Pop nums[i] and place at
        // the back of the vector
        curr.pop_back();
    }
}
 
// Function to pre-process the vector num
vector > permuteDuplicates(
    vector& nums)
{
    // Sort the array
    sort(nums.begin(), nums.end());
 
    // Stores distinct permutations
    vector > ans;
 
    vector visited(
        (int)nums.size(), false);
 
    // Store the current permutation
    vector curr;
 
    // Find the distinct permutations of num
    backtrack(nums, curr, ans, visited);
 
    return ans;
}
 
// Function call to print all distinct
// permutations of the vector nums
void getDistinctPermutations(vector nums)
{
    // Find the distinct permutations
    vector > ans
        = permuteDuplicates(nums);
 
    // Traverse every row
    for (int i = 0; i < (int)ans.size();
         i++) {
 
        // Traverse every column
        for (int j = 0; j < (int)ans[i].size();
             j++) {
 
            cout << ans[i][j] << " ";
        }
 
        cout << '\n';
    }
}
 
// Driver Code
int main()
{
    // Input
    vector nums = { 1, 2, 2 };
 
    // Function call to print
    // all distinct permutations
    getDistinctPermutations(nums);
 
    return 0;
}


Java
// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
class GFG {
 
  static ArrayList nums = new ArrayList();
  static ArrayList curr = new ArrayList();
  static ArrayList> ans = new ArrayList>();
  static ArrayList visited = new ArrayList();
 
  // Function to fill the vector curr
  // while maintaining the indices visited
  // in the array num
  static void backtrack()
  {
 
    // If current permutation is complete
    if (curr.size() == nums.size())
    {
      ans.add(curr);
      for(int i = 0; i < curr.size(); i++)
      {
        System.out.print(curr.get(i) +" ");
      }
      System.out.println();
    }
 
    // Traverse the input vector
    for (int i = 0; i < (int)nums.size();
         i++)
    {
 
      // If index is already visited
      if (visited.get(i))
        continue;
 
      // If the numebr is dupicate
      if (i > 0 && (nums.get(i) == nums.get(i - 1)) && !visited.get(i - 1))
        continue;
 
      // Set visited[i] flag as true
      visited.set(i, true);
 
      // Push nums[i] to current vector
      curr.add(nums.get(i));
 
      // Recursive function call
      backtrack();
 
      // Backtrack to the previous
      // state by unsetting visited[i]
      visited.set(i, false);
 
      // Pop nums[i] and place at
      // the back of the vector
      curr.remove(curr.size() - 1);
    }
  }
  // Function to pre-process the vector num
  static ArrayList> permuteDuplicates()
  {
    // Sort the array
    Collections.sort(nums);
 
    for(int i = 0; i < nums.size(); i++)
    {
      visited.add(false);
    }
 
    // Find the distinct permutations of num
    backtrack();
 
    return ans;
 
  }
 
  // Function call to print all distinct
  // permutations of the vector nums
 
  static void getDistinctPermutations()
  {
    ans = permuteDuplicates();
 
 
  }
 
  // Driver code
  public static void main (String[] args)
  {
 
    // Input
    nums.add(1);
    nums.add(2);
    nums.add(2);
 
    // Function call to print
    // all distinct permutations
    getDistinctPermutations();
  }
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 Program to implement
# the above approach
 
# Function to fill the vector curr
# while maintaining the indices visited
# in the array num
def backtrack():
    global ans, curr, visited, nums
     
    # If current permutation is complete
    # print(ans)
    if (len(curr) == len(nums)):
        print(*curr)
 
    # Traverse the input vector
    for i in range(len(nums)):
 
        # If index is already visited
        if (visited[i]):
            continue
 
        # If the numebr is dupicate
        if (i > 0 and nums[i] == nums[i - 1] and visited[i - 1]==False):
            continue
 
        # Set visited[i] flag as true
        visited[i] = True
 
        # Push nums[i] to current vector
        curr.append(nums[i])
 
        # Recursive function call
        backtrack()
 
        # Backtrack to the previous
        # state by unsetting visited[i]
        visited[i] = False
 
        # Pop nums[i] and place at
        # the back of the vector
        del curr[-1]
 
# Function to pre-process the vector num
def permuteDuplicates(nums):
    global ans, visited, curr
    nums = sorted(nums)
 
    # Find the distinct permutations of num
    backtrack()
    return ans
 
# Function call to print all distinct
# permutations of the vector nums
def getDistinctPermutations(nums):
    global ans, curr, visited
     
    # Find the distinct permutations
    ans = permuteDuplicates(nums)
 
# Driver Code
if __name__ == '__main__':
    visited = [False]*(5)
    ans,curr = [], []
    nums = [1, 2, 2]
 
    # Function call to print
    # all distinct permutations
    getDistinctPermutations(nums)
 
    # This code is contributed by mohit kumar 29.


C#
// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
 
public class GFG{
 
  static List nums = new List();
  static List curr = new List();
  static List> ans = new List>();
  static List visited = new List();
 
  // Function to fill the vector curr
  // while maintaining the indices visited
  // in the array num
  static void backtrack()
  {
 
    // If current permutation is complete
    if (curr.Count == nums.Count)
    {
      ans.Add(curr);
      for(int i = 0; i < curr.Count; i++)
      {
        Console.Write(curr[i] +" ");
      }
      Console.WriteLine();
    }
 
    // Traverse the input vector
    for (int i = 0; i < (int)nums.Count;
         i++)
    {
 
      // If index is already visited
      if (visited[i])
        continue;
 
      // If the numebr is dupicate
      if (i > 0 && (nums[i] == nums[i-1]) && !visited[i-1])
        continue;
 
      // Set visited[i] flag as true
      visited[i] = true;
 
      // Push nums[i] to current vector
      curr.Add(nums[i]);
 
      // Recursive function call
      backtrack();
 
      // Backtrack to the previous
      // state by unsetting visited[i]
      visited[i] = false;
 
      // Pop nums[i] and place at
      // the back of the vector
      curr.RemoveAt(curr.Count - 1);
    }
  }
 
  // Function to pre-process the vector num
  static List> permuteDuplicates()
  {
    // Sort the array
    nums.Sort();
 
    for(int i = 0; i < nums.Count; i++)
    {
      visited.Add(false);
    }
 
    // Find the distinct permutations of num
    backtrack();
 
    return ans;
 
  }
 
  // Function call to print all distinct
  // permutations of the vector nums
 
  static void getDistinctPermutations()
  {
    ans = permuteDuplicates();
 
 
  }
 
  // Driver code
  static public void Main (){
 
    // Input
    nums.Add(1);
    nums.Add(2);
    nums.Add(2);
 
    // Function call to print
    // all distinct permutations
    getDistinctPermutations();
 
  }
}
 
// This code is contributed by rag2127


输出:
1 2 2 
2 1 2 
2 2 1

时间复杂度: O(N!* N)
辅助空间:O(N!* N)