Print all distinct permutations of a given string with duplicates - GeeksforGeeks

18 Apr, 2022
Given a string that may contain duplicates, write a function to print all permutations of given string such that no permutation is repeated in output.Examples: 
Input:  str[] = "AB"
Output: AB BA

Input:  str[] = "AA"
Output: AA

Input:  str[] = "ABC"
Output: ABC ACB BAC BCA CBA CAB

Input:  str[] = "ABA"
Output: ABA AAB BAA

Input:  str[] = "ABCA"
Output: AABC AACB ABAC ABCA ACBA ACAB BAAC BACA 
        BCAA CABA CAAB CBAA
We have discussed an algorithm to print all permutations in below post. It is strongly recommended to refer below post as a prerequisite of this post.Write a C program to print all permutations of a given stringThe algorithm discussed on above link doesn’t handle duplicates. 
CPP
C
// Program to print all permutations of a// string in sorted order.#include <bits/stdc++.h>using namespace std; /* Following function is needed for library  function qsort(). */int compare(const void* a, const void* b){    return (*(char*)a - *(char*)b);} // A utility function two swap two characters a and bvoid swap(char* a, char* b){    char t = *a;    *a = *b;    *b = t;} // This function finds the index of the smallest character// which is greater than 'first' and is present in str[l..h]int findCeil(char str[], char first, int l, int h){    // initialize index of ceiling element    int ceilIndex = l;     // Now iterate through rest of the elements and find the    // smallest character greater than 'first'    for (int i = l + 1; i <= h; i++)        if (str[i] > first && str[i] < str[ceilIndex])            ceilIndex = i;     return ceilIndex;} // Print all permutations of str in sorted ordervoid sortedPermutations(char str[]){    // Get size of string    int size = strlen(str);    // Sort the string in increasing order    qsort(str, size, sizeof(str[0]), compare);    // Print permutations one by one    bool isFinished = false;    while (!isFinished) {        // print this permutation        static int x = 1;        cout << x++ << " " << str << endl;        // printf("%d  %s \n", x++, str);        // Find the rightmost character which is smaller        // than its next character. Let us call it 'first        // char'        int i;        for (i = size - 2; i >= 0; --i)            if (str[i] < str[i + 1])                break;        // If there is no such character, all are sorted in        // decreasing order, means we just printed the last        // permutation and we are done.        if (i == -1)            isFinished = true;        else {            // Find the ceil of 'first char' in right of            // first character. Ceil of a character is the            // smallest character greater than it            int ceilIndex = findCeil(str, str[i], i + 1, size - 1);            // Swap first and second characters            swap(&str[i], &str[ceilIndex]);            // Sort the string on right of 'first char'            qsort(str + i + 1, size - i - 1, sizeof(str[0]), compare);        }    }} // Driver program to test above functionint main(){    char str[] = "ACBC";    sortedPermutations(str);    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Program to print all permutations of a string in sorted// order.#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <string.h> /* Following function is needed for library  function qsort(). */int compare(const void* a, const void* b){    return (*(char*)a - *(char*)b);} // A utility function two swap two characters// a and bvoid swap(char* a, char* b){    char t = *a;    *a = *b;    *b = t;} // This function finds the index of the smallest character// which is greater than 'first' and is present in str[l..h]int findCeil(char str[], char first, int l, int h){    // initialize index of ceiling element    int ceilIndex = l;    // Now iterate through rest of the elements and find the    // smallest character greater than 'first'    for (int i = l + 1; i <= h; i++)        if (str[i] > first && str[i] < str[ceilIndex])            ceilIndex = i;    return ceilIndex;} // Print all permutations of str in sorted ordervoid sortedPermutations(char str[]){    // Get size of string    int size = strlen(str);    // Sort the string in increasing order    qsort(str, size, sizeof(str[0]), compare);    // Print permutations one by one    bool isFinished = false;    while (!isFinished) {        // print this permutation        static int x = 1;        printf("%d  %s \n", x++, str);        // Find the rightmost character which is smaller        // than its next character. Let us call it 'first        // char'        int i;        for (i = size - 2; i >= 0; --i)            if (str[i] < str[i + 1])                break;        // If there is no such character, all are sorted in        // decreasing order, means we just printed the last        // permutation and we are done.        if (i == -1)            isFinished = true;        else {            // Find the ceil of 'first char' in right of            // first character. Ceil of a character is the            // smallest character greater than it            int ceilIndex = findCeil(str, str[i], i + 1, size - 1);            // Swap first and second characters            swap(&str[i], &str[ceilIndex]);            // Sort the string on right of 'first char'            qsort(str + i + 1, size - i - 1, sizeof(str[0]), compare);        }    }} // Driver program to test above functionint main(){    char str[] = "ACBC";    sortedPermutations(str);    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
1  ABCC 
2  ACBC 
3  ACCB 
4  BACC 
5  BCAC 
6  BCCA 
7  CABC 
8  CACB 
9  CBAC 
10  CBCA 
11  CCAB 
12  CCBA 
The above code is taken from a comment below by Mr. Lazy.Time Complexity: O(n2 * n!) Auxiliary Space: O(1)
The above algorithm is in the time complexity of O(n2 * n!)  but we can achieve a better time complexity of O(n!*n) which was there in the case of all distinct characters in the input by some modification in that algorithm. The distinct characters algorithm can be found here – https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/ 
Efficient Approach: In our recursive function to find all permutations, we can use unordered_set for taking care of duplicate element remaining in the active string. While iterating over the elements of the string, we will check for that element in the unordered_set and if it found then we will skip that iteration or otherwise we will insert that element into unordered_set. As on an average all the unordered_set operations like insert() and find() are in O(1) time then the algorithm time complexity will not change by using unordered_set.
The algorithm implementation is as follows – 
C++
Javascript
#include <bits/stdc++.h>using namespace std; void printAllPermutationsFast(string s, string l){    if (s.length() < 1)        cout << l + s << endl;    unordered_set<char> uset;    for (int i = 0; i < s.length(); i++)    {        if (uset.find(s[i]) != uset.end())            continue;        else            uset.insert(s[i]);        string temp = "";        if (i < s.length() - 1)            temp = s.substr(0, i) + s.substr(i + 1);        else            temp = s.substr(0, i);        printAllPermutationsFast(temp, l + s[i]);    }} int main(){    string s = "ACBC";    sort(s.begin(), s.end());    printAllPermutationsFast(s, "");    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
<script> // JavaScript code for the same approach function printAllPermutationsFast(s, l){    if (s.length < 1) {        document.write(l + s,"</br>");    }    let uset = new Set();    for (let i = 0; i < s.length; i++) {        if (uset.has(s[i]) == true) {            continue;        }        else {            uset.add(s[i]);        }        let temp = "";        if (i < s.length - 1) {            temp = s.substring(0, i) + s.substring(i + 1);        }        else {            temp = s.substring(0, i);        }        printAllPermutationsFast(temp, l + s[i]);    }} // driver codelet s = "ACBC";s = s.split("").sort().join("");printAllPermutationsFast(s, ""); // This code is contributed by shinjanpatra.</script>
ABCC
ACBC
ACCB
BACC
BCAC
BCCA
CABC
CACB
CBAC
CBCA
CCAB
CCBA
Time Complexity – O(n*n!)Auxiliary Space – O(n) 
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
jatinrao361
shinjanpatra
adityakumar129
permutation
Combinatorial
Mathematical
Mathematical
permutation
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Python program to get all subsets of given size of a set
Distinct permutations of the string | Set 2
Make all combinations of size k
Count Derangements (Permutation such that no element appears in its original position)
Print all subsets of given size of a set
Program for Fibonacci numbers
C++ Data Types
Set in C++ Standard Template Library (STL)
Coin Change | DP-7
Merge two sorted arrays