Open In App

Print all palindrome permutations of a string

Last Updated : 13 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string s, consisting of lowercase Latin characters [a-z]. Find out all the possible palindromes that can be generated using the letters of the string and print them in lexicographical order.

Note: Return an empty array if no possible palindromic string can be formed.

Examples:

Input: s = aabcb
Output: { abcba bacab }
Explanation: "abcba" and "bacab" are possible strings that are palindrome.

Input: abc
Output: { }
Explanation: No possible palindromic string can be formed.

Approach:

The idea is to generate all permutations of the first half of the palindromic string and then concatenate its reverse to complete the whole string.

  • Create an array freq[] of size 26, to store the frequency of all the characters in string s.
  • Now check if the palindromic string can be formed using all the characters. Palindromic string can be formed if all the characters have even count or only one character has odd count.
  • If the condition is not satisfied, return the empty array, else construct the first half by considering the half frequency of each letter of string s.
  • Now traverse through all possible permutation of this half string and each time add reverse of this part at the end and add odd frequency character in mid between if string is of odd length, for making the palindrome.

Below is given the implementation

C++
// C++ program to print all palindromic 
// permutations of a given string
#include <bits/stdc++.h>
using namespace std;

// Function to find all possible
// palindromic strings of s
vector<string> all_palindromes(string &s) {
    
    // frequency array to count frequencies
    // of all characters of string s
    vector<int> freq(26, 0);
    for(auto i:s) {
        freq[i - 'a']++;
    }

    // odd will keep the count of letters
    // with odd occurrence
    int odd = 0;
    for(auto i:freq) {
        if(i % 2 != 0) {
            odd++;
        }
    }

    // if more than one letter have
    // odd frequency, return empty array
    if(odd > 1) 
        return {};

    int n = s.length();

    // to store first half of palindrome
    string half = "";

    // to store character with odd occurrence
    char oddC;

    for (int i = 0; i < 26; i++) {

        // store the character with odd frequency
        if(freq[i] % 2 == 1)
            oddC = i + 'a';

        // add half of the characters
        for(int j = 0; j < freq[i] / 2; j++) {
            half += (i + 'a');
        }
    }

    // to store all possible palindromic string
    vector<string> res;

    // generate all permutation of first half, and add
    // reverse of it at end. Also, add the character with
    // odd frequency in the mid
    do {

        string cur = half;

        // to store the reversed half
        string rev = cur;
        reverse(rev.begin(), rev.end());
        
        // add the character with odd frequency
        if (n % 2 == 1)
            cur += oddC;

        // add the reversed string
        cur += rev;
        res.push_back(cur);
    }
    // generate next permutation of first half
    while (next_permutation(half.begin(), half.end()));

    return res;
}

int main() {
    string s = "aabcb";
    vector<string> ans = all_palindromes(s);
    cout<< "{ ";
    for(auto i:ans) {
        cout<<i<<" ";
    }
    cout<<"}";
    return 0;
}
Java
// Java program to print all palindromic 
// permutations of a given string
import java.util.*;

class GfG {

    // Function to find all possible
    // palindromic strings of s
    static List<String> all_palindromes(String s) {

        // frequency array to count frequencies
        // of all characters of string s
        int[] freq = new int[26];
        for (char i : s.toCharArray()) {
            freq[i - 'a']++;
        }

        // odd will keep the count of letters
        // with odd occurrence
        int odd = 0;
        for (int i : freq) {
            if (i % 2 != 0) {
                odd++;
            }
        }

        // if more than one letter have
        // odd frequency, return empty array
        if (odd > 1)
            return new ArrayList<>();

        int n = s.length();

        // to store first half of palindrome
        StringBuilder half = new StringBuilder();

        // to store character with odd occurrence
        char oddC = 0;

        for (int i = 0; i < 26; i++) {

            // store the character with odd frequency
            if (freq[i] % 2 == 1)
                oddC = (char) (i + 'a');

            // add half of the characters
            for (int j = 0; j < freq[i] / 2; j++) {
                half.append((char) (i + 'a'));
            }
        }

        // to store all possible palindromic strings
        List<String> res = new ArrayList<>();

        // generate all permutations of first half
        char[] halfArray = half.toString().toCharArray();
        Arrays.sort(halfArray); // Sort once
        do {
            String cur = new String(halfArray);

            // to store the reversed half
            String rev = new StringBuilder(cur).reverse().toString();

            // add the character with odd frequency
            if (n % 2 == 1)
                cur += oddC;

            // add the reversed string
            cur += rev;
            res.add(cur);

        } while (next_permutation(halfArray)); // Efficient permutation generation

        return res;
    }

    // Helper function to generate next permutation
    static boolean next_permutation(char[] array) {
        int n = array.length, k = n - 2;

        // Find the first character that is smaller than the next one
        while (k >= 0 && array[k] >= array[k + 1]) k--;

        // If no such character is found, the array is in descending order
        if (k < 0) return false;

        // Find the smallest character on the right of k and greater than array[k]
        int l = n - 1;
        while (array[l] <= array[k]) l--;

        // Swap the two characters
        char temp = array[k];
        array[k] = array[l];
        array[l] = temp;

        // Reverse the sequence after index k
        int start = k + 1, end = n - 1;
        while (start < end) {
            temp = array[start];
            array[start] = array[end];
            array[end] = temp;
            start++;
            end--;
        }
        return true;
    }

    public static void main(String[] args) {
        String s = "aabcb";
        List<String> ans = all_palindromes(s);
        System.out.print("{ ");
        for (String i : ans) {
            System.out.print(i + " ");
        }
        System.out.println("}");
    }
}
Python
# Python program to print all palindromic 
# permutations of a given string
from itertools import permutations

# Function to find all possible
# palindromic strings of s
def all_palindromes(s):

    # frequency array to count frequencies
    # of all characters of string s
    freq = [0] * 26
    for i in s:
        freq[ord(i) - ord('a')] += 1

    # odd will keep the count of letters
    # with odd occurrence
    odd = 0
    for i in freq:
        if i % 2 != 0:
            odd += 1

    # if more than one letter have
    # odd frequency, return empty array
    if odd > 1:
        return []

    n = len(s)

    # to store first half of palindrome
    half = ""

    # to store character with odd occurrence
    oddC = ''

    for i in range(26):

        # store the character with odd frequency
        if freq[i] % 2 == 1:
            oddC = chr(i + ord('a'))

        # add half of the characters
        for j in range(freq[i] // 2):
            half += chr(i + ord('a'))

    # to store all possible palindromic string
    res = []

    # generate all permutation of first half, and add
    # reverse of it at end. Also, add the character with
    # odd frequency in the mid
    for perm in set(permutations(half)):
        cur = ''.join(perm)

        # to store the reversed half
        rev = cur[::-1]

        # add the character with odd frequency
        if n % 2 == 1:
            cur += oddC

        # add the reversed string
        cur += rev
        res.append(cur)

    return res

if __name__ == "__main__":
    s = "aabcb"
    ans = all_palindromes(s)
    print("{", " ".join(ans), "}")
C#
// C# program to print all palindromic 
// permutations of a given string
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {

    // Function to find all possible
    // palindromic strings of s
    static List<string> all_palindromes(string s) {

        // frequency array to count frequencies
        // of all characters of string s
        int[] freq = new int[26];
        foreach (char i in s) {
            freq[i - 'a']++;
        }

        // odd will keep the count of letters
        // with odd occurrence
        int odd = 0;
        foreach (int i in freq) {
            if (i % 2 != 0) {
                odd++;
            }
        }

        // if more than one letter have
        // odd frequency, return empty array
        if (odd > 1)
            return new List<string>();

        int n = s.Length;

        // to store first half of palindrome
        string half = "";

        // to store character with odd occurrence
        char oddC = '\0';

        for (int i = 0; i < 26; i++) {

            // store the character with odd frequency
            if (freq[i] % 2 == 1)
                oddC = (char)(i + 'a');

            // add half of the characters
            for (int j = 0; j < freq[i] / 2; j++) {
                half += (char)(i + 'a');
            }
        }

        // to store all possible palindromic string
        List<string> res = new List<string>();

        // generate all permutation of first half, and add
        // reverse of it at end. Also, add the character with
        // odd frequency in the mid
        char[] halfArray = half.ToCharArray();
        Array.Sort(halfArray);

        do {
            string cur = new string(halfArray);

            // to store the reversed half
            string rev = new string(cur.Reverse().ToArray());

            // add the character with odd frequency
            if (n % 2 == 1)
                cur += oddC;

            // add the reversed string
            cur += rev;
            res.Add(cur);

        } while (NextPermutation(halfArray));

        return res;
    }

    // Helper function to generate next permutation
    static bool NextPermutation(char[] array) {
        int n = array.Length, k = n - 2;
        while (k >= 0 && array[k] >= array[k + 1]) k--;
        if (k < 0) return false;
        int l = n - 1;
        while (array[l] <= array[k]) l--;
        char temp = array[k];
        array[k] = array[l];
        array[l] = temp;
        Array.Reverse(array, k + 1, n - k - 1);
        return true;
    }

    static void Main(string[] args) {
        string s = "aabcb";
        List<string> ans = all_palindromes(s);
        Console.Write("{ ");
        foreach (string i in ans) {
            Console.Write(i + " ");
        }
        Console.WriteLine("}");
    }
}
JavaScript
// JavaScript program to print all palindromic 
// permutations of a given string

// Function to find all possible
// palindromic strings of s
function all_palindromes(s) {

    // frequency array to count frequencies
    // of all characters of string s
    let freq = Array(26).fill(0);
    for (let i of s) {
        freq[i.charCodeAt(0) - 'a'.charCodeAt(0)]++;
    }

    // odd will keep the count of letters
    // with odd occurrence
    let odd = 0;
    for (let i of freq) {
        if (i % 2 != 0) {
            odd++;
        }
    }

    // if more than one letter have
    // odd frequency, return empty array
    if (odd > 1)
        return [];

    let n = s.length;

    // to store first half of palindrome
    let half = "";

    // to store character with odd occurrence
    let oddC = '';

    for (let i = 0; i < 26; i++) {

        // store the character with odd frequency
        if (freq[i] % 2 == 1)
            oddC = String.fromCharCode(i + 'a'.charCodeAt(0));

        // add half of the characters
        for (let j = 0; j < Math.floor(freq[i] / 2); j++) {
            half += String.fromCharCode(i + 'a'.charCodeAt(0));
        }
    }

    // to store all possible palindromic string
    let res = [];

    // generate all permutation of first half, and add
    // reverse of it at end. Also, add the character with
    // odd frequency in the mid
    let halfArray = [...half].sort();
    do {
        let cur = halfArray.join('');

        // to store the reversed half
        let rev = cur.split('').reverse().join('');

        // add the character with odd frequency
        if (n % 2 == 1)
            cur += oddC;

        // add the reversed string
        cur += rev;
        res.push(cur);

    } while (nextPermutation(halfArray));

    return res;
}

// Helper function to generate next permutation
function nextPermutation(array) {
    let n = array.length, k = n - 2;
    while (k >= 0 && array[k] >= array[k + 1]) k--;
    if (k < 0) return false;
    let l = n - 1;
    while (array[l] <= array[k]) l--;
    [array[k], array[l]] = [array[l], array[k]];
    let start = k + 1, end = n - 1;
    while (start < end) {
        [array[start], array[end]] = [array[end], array[start]];
        start++;
        end--;
    }
    return true;
}

// Driver code
let s = "aabcb";
let ans = all_palindromes(s);
console.log("{ " + ans.join(" ") + " }");

Output
{ abcba bacab }

Time Complexity: O((n / 2)!), where n is the length of the string s.
Auxiliary Space: O(1)


Next Article

Similar Reads