Print All Distinct Permutations of an Array
Last Updated :
24 Apr, 2025
Improve
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.
Try it on GfG Practice
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++ 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;
}
// C++ Program to generate unique permutations
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 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 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# 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 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.
All Unique Permutations of an array | DSA Problem