Skip to content
Related Articles

Related Articles

Print all possible permutations of an array with duplicates using Backtracking
  • Last Updated : 03 Mar, 2021

Given an array nums[] of size N, the task is to print all possible distinct permutations of the array nums[] (including duplicates).

Input: nums[] = { 1, 2, 2 }
Output: 
1 2 1
2 1 2
2 2 1

Input: nums[] = { 1, 1 }
Output: 1 1

Approach : Follow the steps below to solve the problem

  1. Traverse the array.
  2. Generate permutations of an array.
  3. Set an order of selection among duplicate elements.
  4. If i > 0 && nums[i] == nums[i – 1]: Add nums[i] in the current permutation only if nums[i – 1] has been added in the permutation, i.e visited[i – 1] is true.
  5. Otherwise, continue.
  6. Using this approach, print the distinct permutations generated.

Check this Recursion Tree to understand the implementation details of the code.



Below is the implementation of the above approach:

C++14




// C++ Program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to fill the vector curr
// while maintaining the indices visited
// in the array num
void backtrack(vector<int>& nums,
               vector<int>& curr,
               vector<vector<int> >& ans,
               vector<bool>& 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<vector<int> > permuteDuplicates(
    vector<int>& nums)
{
    // Sort the array
    sort(nums.begin(), nums.end());
 
    // Stores distinct permutations
    vector<vector<int> > ans;
 
    vector<bool> visited(
        (int)nums.size(), false);
 
    // Store the current permutation
    vector<int> 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<int> nums)
{
    // Find the distinct permutations
    vector<vector<int> > 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<int> 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<Integer> nums = new ArrayList<Integer>();
  static ArrayList<Integer> curr = new ArrayList<Integer>();
  static ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
  static ArrayList<Boolean> visited = new ArrayList<Boolean>();
 
  // 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<ArrayList<Integer>> 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<int> nums = new List<int>();
  static List<int> curr = new List<int>();
  static List<List<int>> ans = new List<List<int>>();
  static List<bool> visited = new List<bool>();
 
  // 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<List<int>> 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

 
 

Output: 
1 2 2 
2 1 2 
2 2 1

 

 

Time Complexity: O(N! * N)
Auxiliary Space : O(N! * N)

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :