Distinct permutations of the string | Set 2

Print all distinct permutation of a string having duplicates.

Examples:  

Input : ABCA
Output : AABC AACB ABAC ABCA ACBA 
         ACAB BAAC BACA BCAA CABA 
         CAAB CBAA

An algorithm to print all distinct permutations has already been discussed here. Here we’ll discuss one more approach to do the same. Recall first how we print permutations without any duplicates in the input string. It is given here. Let’s now take the case of the string “ABAC”. While generating permutations, let’s say we are at index = 0, swap it with all elements after it. When we reach at i=2, we see that in the string s[index…i-1], there was an index which is equal to s[i]. Thus, swapping it will produce repeated permutations. Thus, we don’t swap it. The below explains it better.

Illustration: Let us understand with below example. 

i = 0 1 2 3
    A B A C
index = 0, s[0] = A
Start swapping s[index] with s[i] following it:
i = index + 1 = 1 

Since s[index] != s[i], swap and recur.

i = 2, s[index] == s[i], don't swap

i = 3,  s[index] != s[i], swap and recur. 

Below code does the same. 



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to distinct permutations of the string
#include <bits/stdc++.h>
using namespace std;
 
// Returns true if str[curr] does not matches with any of the
// characters after str[start]
bool shouldSwap(char str[], int start, int curr)
{
    for (int i = start; i < curr; i++)
        if (str[i] == str[curr])
            return 0;
    return 1;
}
 
// Prints all distinct permutations in str[0..n-1]
void findPermutations(char str[], int index, int n)
{
    if (index >= n) {
        cout << str << endl;
        return;
    }
 
    for (int i = index; i < n; i++) {
 
        // Proceed further for str[i] only if it
        // doesn't match with any of the characters
        // after str[index]
        bool check = shouldSwap(str, index, i);
        if (check) {
            swap(str[index], str[i]);
            findPermutations(str, index + 1, n);
            swap(str[index], str[i]);
        }
    }
}
 
// Driver code
int main()
{
    char str[] = "ABCA";
    int n = strlen(str);
    findPermutations(str, 0, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to distinct permutations of the string
public class GFG {
 
// Returns true if str[curr] does not matches with any of the
// characters after str[start]
    static boolean shouldSwap(char str[], int start, int curr) {
        for (int i = start; i < curr; i++) {
            if (str[i] == str[curr]) {
                return false;
            }
        }
        return true;
    }
 
// Prints all distinct permutations in str[0..n-1]
    static void findPermutations(char str[], int index, int n) {
        if (index >= n) {
            System.out.println(str);
            return;
        }
 
        for (int i = index; i < n; i++) {
 
            // Proceed further for str[i] only if it
            // doesn't match with any of the characters
            // after str[index]
            boolean check = shouldSwap(str, index, i);
            if (check) {
                swap(str, index, i);
                findPermutations(str, index + 1, n);
                swap(str, index, i);
            }
        }
    }
 
    static void swap(char[] str, int i, int j) {
        char c = str[i];
        str[i] = str[j];
        str[j] = c;
    }
 
    // Driver code
    public static void main(String[] args) {
 
        char str[] = {'A', 'B', 'C', 'A'};
        int n = str.length;
        findPermutations(str, 0, n);
    }
 
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to distinct
# permutations of the string
 
# Returns true if str[curr] does not
# matches with any of the characters
# after str[start]
def shouldSwap(string, start, curr):
 
    for i in range(start, curr):
        if string[i] == string[curr]:
            return 0
    return 1
 
# Prints all distinct permutations
# in str[0..n-1]
def findPermutations(string, index, n):
 
    if index >= n:
        print(''.join(string))
        return
 
    for i in range(index, n):
 
        # Proceed further for str[i] only
        # if it doesn't match with any of
        # the characters after str[index]
        check = shouldSwap(string, index, i)
        if check:
            string[index], string[i] = string[i], string[index]
            findPermutations(string, index + 1, n)
            string[index], string[i] = string[i], string[index]
 
# Driver code
if __name__ == "__main__":
 
    string = list("ABCA")
    n = len(string)
    findPermutations(string, 0, n)
     
# This code is contributed by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to distinct permutations
// of the string
using System;
 
class GFG
{
 
// Returns true if str[curr] does
// not matches with any of the
// characters after str[start]
static bool shouldSwap(char []str,
                       int start, int curr)
{
    for (int i = start; i < curr; i++)
    {
        if (str[i] == str[curr])
        {
            return false;
        }
    }
    return true;
}
 
// Prints all distinct permutations
// in str[0..n-1]
static void findPermutations(char []str,
                             int index, int n)
{
    if (index >= n)
    {
        Console.WriteLine(str);
        return;
    }
 
    for (int i = index; i < n; i++)
    {
 
        // Proceed further for str[i] only
        // if it doesn't match with any of
        // the characters after str[index]
        bool check = shouldSwap(str, index, i);
        if (check)
        {
            swap(str, index, i);
            findPermutations(str, index + 1, n);
            swap(str, index, i);
        }
    }
}
 
static void swap(char[] str, int i, int j)
{
    char c = str[i];
    str[i] = str[j];
    str[j] = c;
}
 
// Driver code
public static void Main()
{
    char []str = {'A', 'B', 'C', 'A'};
    int n = str.Length;
    findPermutations(str, 0, n);
}
}
 
// This code is contributed
// by 29AjayKumar

chevron_right


Output

ABCA
ABAC
ACBA
ACAB
AACB
AABC
BACA
BAAC
BCAA
CBAA
CABA
CAAB


Better Approach:

Generate all distinct strings is to simply use some if conditions. The technique above uses an extra loop inside the recursion which causes a major time complexity cost. Instead, we can improve it by little pre-processing. We first sort the given string and then apply the below code.

Below is the implementation of the above idea:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to print all the permutation
// of the given string.
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
 
// count of total permutations
int total = 0;
 
void permute(int i, string s)
{
    // base case
    if (i == (s.length() - 1)) {
        cout << s << endl;
        total++;
        return;
    }
   
    char prev = '*';
   
    // loop from j = 1 to length of string
    for (int j = i; j < s.length(); j++) {
        string temp = s;
        if (j > i && temp[i] == temp[j])
            continue;
        if (prev != '*' && prev == s[j]) {
            continue;
        }
       
        // swap the elements
        swap(temp[i], temp[j]);
        prev = s[j];
       
        // recursion call
        permute(i + 1, temp);
    }
}
 
// Driver code
int main()
{
    string s = "abca";
     
    // sort
    sort(s.begin(), s.end());
   
    // Function call
    permute(0, s);
    cout << "Total distinct permutations = " << total
         << endl;
    return 0;
}
 
// This code is contributed by risingStark.

chevron_right


Output

aabc
aacb
abac
abca
acba
acab
baac
baca
bcaa
caba
caab
cbaa
Total distinct permutations = 12

Time complexity: If we take the length of string to be N, then the complexity of my code will be O(N log N) for sorting and O(N*N!) for the permutation. Total time complexity would be O(N log N + N*N!) which is effectively only O(N*N!).

This article is contributed by ekta1994

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 

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

Article Tags :
Practice Tags :


4


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.