Print all Unique permutations of a given string. (original) (raw)

Last Updated : 24 Jan, 2025

Try it on GfG Practice redirect icon

Given a **string that may contain **duplicates, the task is find all **unique permutations of given string in **any order.

**Examples:

**Input: "ABC"
**Output: ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"]
**Explanation: Given string ABC has 6 unique permutations as ****"ABC", "ACB", "BAC", "BCA", "CAB" and "CBA"**.

**Input: "AAA"
**Output: ["AAA"]
**Explanation: No other **unique permutations can be formed as all the **characters are same.

Table of Content

[Naive Approach] Generating All Permutations

The idea is to generate **all **possible **permutations of a given string and store them in a **hash set. The **generated permutations were stored in **hash **set, to ensures that only **unique permutations are retained as **hashset does not allow **duplicates. Once all permutations have been generated, we transfer the permutations from **hash set to the result array.

This method is particularly useful when dealing with input strings that contain **duplicate characters. Instead of manually handling the duplicates during the permutation generation, the use of a **unordered set simplifies the process by eliminating duplicates automatically.

CPP `

// C++ program to print unique permutation of string using hash set.

#include #include #include #include #include

using namespace std;

// Function genPermutation is used to generate all possible permutaion. void genPermutation(int i, string &s, vector &used, string &curr, unordered_set& st) { if (i == s.size()) {

    // Add the permutation to the result set
    st.insert(curr);
    return;
}

for (int j = 0; j < s.size(); j++) {
    if (!used[j]) {

        // Mark the character as used
        used[j] = true;
          curr.push_back(s[j]);
        
        // Recurse with the next character
        genPermutation(i + 1, s, used, curr,st);
          
        // Backtrack and unmark the character
          used[j] = false;
          curr.pop_back();
    }
}

}

vector findPermutation(string &s) {

// To track if a character is used
vector<bool> used(s.size(), false);
unordered_set<string> st;

  string curr = "";

// Start the recursion
genPermutation(0, s, used, curr, st);

// Convert the set to a vector
vector<string> res(st.begin(), st.end());
return res;

}

int main() { string s = "ABC"; vector res = findPermutation(s);

// Print the permutations
for (string perm: res)
    cout << perm << " ";

return 0;

}

Java

// Java program to print unique permutation of string using hash set.

import java.util.ArrayList; import java.util.HashSet;

class GfG {

// Function genPermutation is used to generate all possible permutation.
static void genPermutation(int i, String s, boolean[] used, 
                            StringBuilder curr, HashSet<String> st) {
    if (i == s.length()) {
        // Add the permutation to the result set
        st.add(curr.toString());
        return;
    }

    for (int j = 0; j < s.length(); j++) {
        if (!used[j]) {
            // Mark the character as used
            used[j] = true;
            curr.append(s.charAt(j));
            
            // Recur with the next character
            genPermutation(i + 1, s, used, curr, st);
            
            // Backtrack and unmark the character
            used[j] = false;
            curr.deleteCharAt(curr.length() - 1);
        }
    }
}

static ArrayList<String> findPermutation(String s) {
  
    // To track if a character is used
    boolean[] used = new boolean[s.length()];
    HashSet<String> st = new HashSet<>();
    StringBuilder curr = new StringBuilder();

    // Start the recursion
    genPermutation(0, s, used, curr, st);

    // Convert the set to a list
    return new ArrayList<>(st);
}

public static void main(String[] args) {
    String s = "ABC";
    ArrayList<String> res = findPermutation(s);

    // Print the permutations
    for (String perm : res) {
        System.out.print(perm + " ");
    }
}

}

Python

Python program to print unique permutation of string using hash set.

Function genPermutation is used to generate all possible permutation.

def genPermutation(i, s, used, curr, st): if i == len(s): # Add the permutation to the result set st.add("".join(curr)) return

for j in range(len(s)):
    if not used[j]:
        # Mark the character as used
        used[j] = True
        curr.append(s[j])
        
        # Recurse with the next character
        genPermutation(i + 1, s, used, curr, st)
        
        # Backtrack and unmark the character
        used[j] = False
        curr.pop()

def findPermutation(s): # To track if a character is used used = [False] * len(s) st = set() curr = []

# Start the recursion
genPermutation(0, s, used, curr, st)

# Convert the set to a list
return list(st)

if name == "main": s = "ABC" res = findPermutation(s)

# Print the permutations
for perm in res:
    print(perm, end=" ")

C#

// C# program to print unique permutation of string using hash set.

using System; using System.Collections.Generic;

class GfG {

// Function genPermutation is used to generate all possible permutation.
static void genPermutation(int i, string s, bool[] used, 
                            List<char> curr, HashSet<string> st) {
    if (i == s.Length) {
        // Add the permutation to the result set
        st.Add(new string(curr.ToArray()));
        return;
    }

    for (int j = 0; j < s.Length; j++) {
        if (!used[j]) {
            // Mark the character as used
            used[j] = true;
            curr.Add(s[j]);
            
            // Recurse with the next character
            genPermutation(i + 1, s, used, curr, st);
            
            // Backtrack and unmark the character
            used[j] = false;
            curr.RemoveAt(curr.Count - 1);
        }
    }
}

static List<string> findPermutation(string s) {
    // To track if a character is used
    bool[] used = new bool[s.Length];
    HashSet<string> st = new HashSet<string>();
    List<char> curr = new List<char>();

    // Start the recursion
    genPermutation(0, s, used, curr, st);

    // Convert the set to a list
    return new List<string>(st);
}

static void Main(string[] args) {
    string s = "ABC";
    List<string> res = findPermutation(s);

    // Print the permutations
    foreach (string perm in res) {
        Console.Write(perm + " ");
    }
}

}

JavaScript

// JavaScript program to print unique permutation of string using hash set.

// Function genPermutation is used to generate all possible permutation. function genPermutation(i, s, used, curr, st) { if (i === s.length) { // Add the permutation to the result set st.add(curr.join('')); return; }

for (let j = 0; j < s.length; j++) {
    if (!used[j]) {
        // Mark the character as used
        used[j] = true;
        curr.push(s[j]);
        
        // Recurse with the next character
        genPermutation(i + 1, s, used, curr, st);
        
        // Backtrack and unmark the character
        used[j] = false;
        curr.pop();
    }
}

}

function findPermutation(s) { // To track if a character is used let used = Array(s.length).fill(false); let st = new Set(); let curr = [];

// Start the recursion
genPermutation(0, s, used, curr, st);

// Convert the set to an array
return Array.from(st);

}

// Driver Code let s = "ABC"; let res = findPermutation(s);

// Print the permutations console.log(res.join(' '));

`

Output

CBA BAC CAB BCA ABC ACB

**Time Complexity: O(n*n!), where n is the size of the array.
**Auxiliary Space: O(n!), space used by hash set.

[Expected Approach] Generating Only Unique Permutations

This approach is similar to generating all possible permutation. Now in this approach, while generating the permutations, at each index during recursion, we only consider the **unique **available characters. To track the availability of characters we use **hash map.

Duplicate permutations are generated in the previous approach because it treats identical characters, like the two 'B's in "ABBC," as distinct due to their indices. For example, when placing a 'B' at an index, choosing the first or second 'B' results in the same permutation (e.g., "ABBC" or "ABBC" again), leading to duplicates.

In this approach, we prune branches in the recursive tree that would generate duplicate permutations and place only unique available characters at each index.

C++ `

//C++ program to print unique permutation of string //using hash map. #include #include #include #include using namespace std;

// Recursive function to generate permutations void genPermutations(int n, string &curr ,unordered_map<char, int> &cnt, vector& res) {

// Base case: If the current permutation length equals the input
// string length, add it to the result
if (curr.size() == n) {
    res.push_back(curr);
    return;
}

// Iterate through each character in the frequency map
for (pair<char, int> it: cnt) {
    char c = it.first;
    int count = it.second;

    // Skip characters with a count of 0
    if (count == 0) 
        continue;

    // Include the character in the current permutation
    curr.push_back(c);

    // Decrease its count in the frequency map
    cnt[c]--;

    // Recur to build the next character in the permutation
    genPermutations(n, curr, cnt , res);

    // Backtrack: Remove the character and restore its count
    curr.pop_back();
    cnt[c]++;
}

}

// Function to find all unique permutations of the input string vector findPermutation(string s) {

// Vector to store the result vector res;

// Frequency map to count occurrences of each character unordered_map<char, int> cnt;

// Populate the frequency map with the characters of the input string
for (char c : s) 
    cnt[c]++;

// To build permutations
string curr = "";
genPermutations(s.size(), curr, cnt, res);
return res;

}

int main() { string s = "ABC"; vector res = findPermutation(s);

for (string perm: res)
    cout << perm << " ";

return 0;

}

Java

//Java program to print unique permutation of string //using hash map. import java.util.*;

class GfG { // Recursive function to generate permutations static void genPermutations(int n, StringBuilder curr, Map<Character, Integer> cnt, List res) {

   // Base case: If the current permutation length equals 
   // to the input string length, add it to the result
    if (curr.length() == n) {
        res.add(curr.toString());
        return;
    }

    // Iterate through each character in the frequency map
    for (Map.Entry<Character, Integer> entry : cnt.entrySet()) {
        char c = entry.getKey();
        int count = entry.getValue();

        // Skip characters with a count of 0
        if (count == 0) 
            continue;

        // Include the character in the current permutation
        curr.append(c);

        // Decrease its count in the frequency map
        cnt.put(c, count - 1);

        // Recur to build the next character in the permutation
        genPermutations(n, curr, cnt, res);

        // Backtrack: Remove the character and restore its count
        curr.deleteCharAt(curr.length() - 1);
        cnt.put(c, count);
    }
}

 // Function to find all unique permutations of the input string
 static ArrayList<String> findPermutation(String s) {
    ArrayList<String> res = new ArrayList<>(); 
   
       // Frequency map to count occurrences of each character
    Map<Character, Integer> cnt = new HashMap<>(); 

    // Populate the frequency map with the characters of the input string
    for (char c : s.toCharArray()) 
        cnt.put(c, cnt.getOrDefault(c, 0) + 1);

    // To build permutations
    StringBuilder curr = new StringBuilder();
    genPermutations(s.length(), curr, cnt, res);
    return res;
}

public static void main(String[] args) {
    String s = "ABC";
    List<String> res = findPermutation(s);

    for (String perm : res) 
        System.out.print(perm + " ");
}

}

Python

#C++ program to print unique permutation of string #using hash map.

Recursive function to generate permutations

def genPermutations(n, curr, cnt, res):

# Base case: If the current permutation length equals 
# the input string length, add it to the result
if len(curr) == n:
    res.append(curr)
    return

# Iterate through each character in the frequency map
for c, count in cnt.items():
    # Skip characters with a count of 0
    if count == 0:
        continue

    # Include the character in the current permutation
    cnt[c] -= 1

    # Recur to build the next character in the permutation
    genPermutations(n, curr + c, cnt, res)

    # Backtrack: Restore the count
    cnt[c] += 1

Function to find all unique permutations of the input string

def findPermutation(s):

 # List to store the result
res = []

 # Frequency map to count occurrences of each character
cnt = {} 

# Populate the frequency map with the characters of the input string
for c in s:
    cnt[c] = cnt.get(c, 0) + 1

# Generate permutations
genPermutations(len(s), "", cnt, res)
return res

if name == "main": s = "ABC" res = findPermutation(s)

print(" ".join(res))

C#

// C# program to print unique permutation of string // using hash map. using System; using System.Collections.Generic;

class GfG {

// Recursive function to generate permutations
static void genPermutations(int n, string curr, 
                       Dictionary<char, int> cnt, List<string> res) {
  
    // Base case: If the current permutation length equals the input
    // string length, add it to the result
    if (curr.Length == n) {
        res.Add(curr);
        return;
    }

    // Iterate through a copy of the dictionary's keys
    foreach (char c in new List<char>(cnt.Keys)) {
        int count = cnt[c];

        // Skip characters with a count of 0
        if (count == 0) 
            continue;

        // Include the character in the current permutation
        curr += c;

        // Decrease its count in the frequency map
        cnt[c]--;

        // Recur to build the next character in the permutation
        genPermutations(n, curr, cnt, res);

        // Backtrack: Remove the character and restore its count
        curr = curr.Remove(curr.Length - 1);
        cnt[c]++;
    }
}

// Function to find all unique permutations of the input string
static List<string> findPermutation(string s) {
    // List to store the result
    List<string> res = new List<string>();
    
    // Frequency map to count occurrences of each character
    Dictionary<char, int> cnt = new Dictionary<char, int>();

    // Populate the frequency map with the characters of the input string
    foreach (char c in s) {
        if (cnt.ContainsKey(c))
            cnt[c]++;
        else
            cnt[c] = 1;
    }

    // To build permutations
    string curr = "";
    genPermutations(s.Length, curr, cnt, res);
    
    // Convert the result list to an array
    return res;
}

static void Main(string[] args) {
    string s = "ABC";
    List<string> res = findPermutation(s);

    foreach (string perm in res) 
        Console.Write(perm + " ");
}

}

JavaScript

//javascript program to print unique permutation of string //using hash map.

// Recursive function to generate permutations function genPermutations(n, curr, cnt, res) {

// Base case: If the current permutation length equals 
// the input string length, add it to the result
if (curr.length === n) {
    res.push(curr);
    return;
}

// Iterate through each character in the frequency map
for (let c in cnt) {
    if (cnt[c] === 0) 
        continue;

    // Include the character in the current permutation
    cnt[c]--;

    // Recur to build the next character in the permutation
    genPermutations(n, curr + c, cnt, res);

    // Backtrack: Restore the count
    cnt[c]++;
}

}

// Function to find all unique permutations of the input string function findPermutation(s) {

// Array to store the result
const res = []; 

// Frequency map to count occurrences of each character
const cnt = {};

// Populate the frequency map with the characters of the input string
for (const c of s) 
    cnt[c] = (cnt[c] || 0) + 1;

// Generate permutations
genPermutations(s.length, "", cnt, res);
return res;

}

// Driver code const s = "ABC"; const res = findPermutation(s);

// Print the permutations console.log(res.join(" "));

`

Output

CBA CAB BCA BAC ACB ABC

**Time Complexity: O(n*n!), In worst case all characters were unique, so it take time equal to generating all permutations.
**Auxiliary Space: O(n), used by temporary string and hash map.