Open In App

Print All Distinct Permutations of an Array

Last Updated : 24 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[], Print all distinct permutations of the given array.

Examples:

Input: arr[] = [1, 3, 3]
Output: [[1, 3, 3], [3, 1, 3], [3, 3, 1]]
Explanation: Above are all distinct permutations of given array.

Input: arr[] = [2, 2]
Output: [[2, 2]]
Explanation: Above are all distinct permutations of given array.

Approach: Using BackTracking

  • We will use backtracking to build all possible permutations by recursively adding unused elements to the current path, marking them as visited.
  • To avoid duplicates we will sort the array first, and skip an element if it’s the same as the previous one and the previous hasn’t been used—this prevents generating repeated permutations.

Step by Step Implementation:

  • Sort the input array to handle duplicates easily.
  • Use a visited[] array to track used indices in the current path.
  • Iterate through each element:
    • Skip if already visited.
    • Skip duplicates if the previous identical element wasn’t used.
  • Add element to path, mark as visited, and recurse.
  • If path is complete, store it in the result.
  • Backtrack by removing the last element and unmarking it.
C++
// C++ Program to generate unique permutations

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void backtrack(vector<int>& arr, vector<bool>& visited,
                    vector<int>& curr,  vector<vector<int>>& result) {

    // If current permutation is complete, add it to the result
    if (curr.size() == arr.size()) {
        result.push_back(curr);
        return;
    }

    // Iterate through the array to build permutations
    for (int i = 0; i < arr.size(); i++) {

        // Skip already visited elements
        if (visited[i]) continue;

        // Skip duplicates: if arr[i] == arr[i-1] and i-1 wasn't used
        if (i > 0 && arr[i] == arr[i - 1] && !visited[i - 1]) continue;

        // Choose arr[i]
        visited[i] = true;
        curr.push_back(arr[i]);

        // Recurse to build the next part of the permutation
        backtrack(arr, visited, curr, result);

        // remove last element and unmark it as visited
        curr.pop_back();
        visited[i] = false;
    }
}

// Function to return all unique permutations
vector<vector<int>> uniquePerms(vector<int>& arr) {

    // Sort the array
    sort(arr.begin(), arr.end());

    vector<vector<int>> result;
    vector<int> curr;
    vector<bool> visited(arr.size(), false);

    // Start backtracking to generate permutations
    backtrack(arr, visited, curr, result);
    
    return result;
}

int main() {

    vector<int> arr = {1, 3, 3};

    vector<vector<int>> permutations = uniquePerms(arr);

    for (const auto& perm : permutations) {
        for (int num : perm) {
            cout << num << " ";
        }
        cout << "\n";
    }

    return 0;
}
Java
// Java Program to generate unique permutations 

import java.util.*;

class GfG {

    // Backtracking function
    static void backtrack(int[] arr, boolean[] visited, 
                    ArrayList<Integer> curr, ArrayList<ArrayList<Integer>> result) {

        // If current permutation is complete, add it to the result
        if (curr.size() == arr.length) {
            result.add(new ArrayList<>(curr));
            return;
        }

        // Iterate through the array to build permutations
        for (int i = 0; i < arr.length; i++) {

            // Skip already visited elements or duplicates
            if (visited[i] || (i > 0 && arr[i] == arr[i - 1] && !visited[i - 1]))
                    continue;

            // Choose arr[i] for the current permutation
            visited[i] = true;
            curr.add(arr[i]);

            // Recursively build the next part of the permutation
            backtrack(arr, visited, curr, result);

            // Backtrack
            curr.remove(curr.size() - 1);
            visited[i] = false;
        }
    }

    // Function to return all unique permutations
    static ArrayList<ArrayList<Integer>> uniquePerms(int[] arr) {

        // Sort the array to handle duplicates
        Arrays.sort(arr);
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        ArrayList<Integer> curr = new ArrayList<>();
        boolean[] visited = new boolean[arr.length];

        // Start the backtracking process
        backtrack(arr, visited, curr, result);
        
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {1, 3, 3};

        ArrayList<ArrayList<Integer>> permutations = uniquePerms(arr);

        for (ArrayList<Integer> perm : permutations) {
            for (int num : perm) {
                System.out.print(num + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python Program to generate unique permutations

def backtrack(arr, visited, curr, result):
    
    # If current permutation is complete, add it to the result
    if len(curr) == len(arr):
        result.append(curr[:])
        return

    # Iterate through the array to build permutations
    for i in range(len(arr)):
        # Skip already visited elements or duplicates
        if visited[i] or (i > 0 and arr[i] == arr[i - 1] and not visited[i - 1]):
            continue

        # Choose arr[i] for the current permutation
        visited[i] = True
        curr.append(arr[i])

        # Recursively build the next part of the permutation
        backtrack(arr, visited, curr, result)

        # Backtrack
        curr.pop()
        visited[i] = False

# Function to return all unique permutations

def uniquePerms(arr):
    # Sort the array to handle duplicates
    arr.sort()
    result = []
    visited = [False] * len(arr)

    # Start the backtracking process
    backtrack(arr, visited, [], result)
    
    return result

if __name__ == "__main__":
    arr = [1, 3, 3]
    permutations = uniquePerms(arr)

    for perm in permutations:
        print(" ".join(map(str, perm)))
C#
/* C# Program to generate unique permutations */

using System;
using System.Collections.Generic;

class GfG {

    // Backtracking function
    static void backtrack(int[] arr, bool[] visited, 
                                   List<int> curr, List<List<int>> result) {

        // If current permutation is complete, add it to the result
        if (curr.Count == arr.Length) {
            result.Add(new List<int>(curr));
            return;
        }

        // Iterate through the array to build permutations
        for (int i = 0; i < arr.Length; i++) {

            // Skip already visited elements or duplicates
            if (visited[i] || (i > 0 && arr[i] == arr[i - 1] && !visited[i - 1]))
                                continue;

            // Choose arr[i] for the current permutation
            visited[i] = true;
            curr.Add(arr[i]);

            // Recursively build the next part of the permutation
            backtrack(arr, visited, curr, result);

            // Backtrack
            curr.RemoveAt(curr.Count - 1);
            visited[i] = false;
        }
    }

    // Function to return all unique permutations
    static List<List<int>> uniquePerms(int[] arr) {

        // Sort the array to handle duplicates
        Array.Sort(arr);
        List<List<int>> result = new List<List<int>>();
        List<int> curr = new List<int>();
        bool[] visited = new bool[arr.Length];

        // Start the backtracking process
        backtrack(arr, visited, curr, result);
        
        return result;
    }

    public static void Main() {
        int[] arr = {1, 3, 3};

        List<List<int>> permutations = uniquePerms(arr);

        foreach (var perm in permutations) {
            Console.WriteLine(string.Join(" ", perm));
        }
    }
}
JavaScript
/* JavaScript Program to generate unique permutations */

// Backtracking function
function backtrack(arr, visited, curr, result) {
    
    // If current permutation is complete, add it to the result
    if (curr.length === arr.length) {
        result.push([...curr]);
        return;
    }

    // Iterate through the array to build permutations
    for (let i = 0; i < arr.length; i++) {
        // Skip already visited elements or duplicates
        if (visited[i] || (i > 0 && arr[i] === arr[i - 1] && !visited[i - 1])) {
            continue;
        }

        // Choose arr[i] for the current permutation
        visited[i] = true;
        curr.push(arr[i]);

        // Recursively build the next part of the permutation
        backtrack(arr, visited, curr, result);

        // Backtrack
        curr.pop();
        visited[i] = false;
    }
}

// Function to return all unique permutations
function uniquePerms(arr) {
    // Sort the array to handle duplicates
    arr.sort((a, b) => a - b);
    let result = [];
    let visited = new Array(arr.length).fill(false);

    // Start the backtracking process
    backtrack(arr, visited, [], result);
    
    return result;
}

// Driver Code
const arr = [1, 3, 3];
const permutations = uniquePerms(arr);

permutations.forEach(perm => {
    console.log(perm.join(" "));
});

Output
1 3 3 
3 1 3 
3 3 1 

Time Complexity: O(n! * n), n! comes from the total number of permutations in the worst case (when all elements are distinct) and n accounts for the time taken to copy each complete permutation (which has n elements) into the result array.
Auxiliary Space: O(n), depth of recursion equals the number of elements and also for visited and curr array.



Next Article

Similar Reads