All Palindromic Permutations

Last Updated : 11 Aug, 2026

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.

Examples:

Input: s = "abbab"
Output: [abbba, babab]
Explanation: abbba and babab are two possible string that are palindrome.

Input: s = "abc"
Output: []
Explanation: No permutation is palindromic.

Try It Yourself
redirect icon

[Naive Approach] Generate All Permutations - O(n * n!) Time and O(n!) Space

The idea is to generate every distinct permutation of the given string and check whether it is a palindrome.

Working of Approach:

  • Sort the string so that next_permutation() generates distinct permutations in lexicographical order.
  • Generate every permutation of the string.
  • Check whether the current permutation is a palindrome.
  • If it is a palindrome, store it in the answer.
  • Return all palindromic permutations.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check whether a string is palindrome.
bool isPalindrome(string &str)
{
    int i = 0, j = str.size() - 1;

    while (i < j)
    {
        if (str[i] != str[j])
            return false;
        i++;
        j--;
    }

    return true;
}

// Function to find all palindromic permutations.
vector<string> allPalindromes(string &s)
{

    vector<string> res;

    // Sort the string to generate distinct permutations.
    sort(s.begin(), s.end());

    // Generate all distinct permutations.
    do
    {

        // If the current permutation is a palindrome,
        // store it in the result.
        if (isPalindrome(s))
            res.push_back(s);

    } while (next_permutation(s.begin(), s.end()));

    return res;
}

int main()
{

    string s = "abbab";

    vector<string> res = allPalindromes(s);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];

        if (i + 1 < res.size())
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.*;

class GFG {

    // Function to check whether a string is palindrome.
    static boolean isPalindrome(String str)
    {
        int i = 0, j = str.length() - 1;

        while (i < j) {
            if (str.charAt(i) != str.charAt(j))
                return false;
            i++;
            j--;
        }

        return true;
    }

    // Function to generate the next lexicographical
    // permutation.
    static boolean nextPermutation(char[] arr)
    {
        int i = arr.length - 2;

        while (i >= 0 && arr[i] >= arr[i + 1])
            i--;

        if (i < 0)
            return false;

        int j = arr.length - 1;
        while (arr[j] <= arr[i])
            j--;

        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        int left = i + 1, right = arr.length - 1;
        while (left < right) {
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }

        return true;
    }

    // Function to find all palindromic permutations.
    static ArrayList<String> allPalindromes(String s)
    {

        ArrayList<String> res = new ArrayList<>();

        char[] arr = s.toCharArray();
        Arrays.sort(arr);

        do {
            String curr = new String(arr);

            if (isPalindrome(curr))
                res.add(curr);

        } while (nextPermutation(arr));

        return res;
    }

    public static void main(String[] args)
    {

        String s = "abbab";

        ArrayList<String> res = allPalindromes(s);

        System.out.print("[");

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));

            if (i + 1 < res.size())
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
from itertools import permutations

# Function to check whether a string is palindrome.


def isPalindrome(str):
    i = 0
    j = len(str) - 1

    while i < j:
        if str[i] != str[j]:
            return False
        i += 1
        j -= 1

    return True

# Function to find all palindromic permutations.


def allPalindromes(s):
    res = []

    # Generate all distinct permutations.
    permuted = sorted(set(permutations(s)))

    for p in permuted:
        p_str = ''.join(p)

        # If the current permutation is a palindrome,
        # store it in the result.
        if isPalindrome(p_str):
            res.append(p_str)

    return res


if __name__ == '__main__':
    s = "abbab"

    res = allPalindromes(s)

    print('[', end='')

    for i in range(len(res)):
        print(res[i], end='')

        if i + 1 < len(res):
            print(', ', end='')

    print(']')
C#
using System;
using System.Collections.Generic;

class GFG {
    // Function to check whether a string is palindrome.
    static bool IsPalindrome(string str)
    {
        int i = 0, j = str.Length - 1;

        while (i < j) {
            if (str[i] != str[j])
                return false;

            i++;
            j--;
        }

        return true;
    }

    // Function to generate the next lexicographical
    // permutation.
    static bool NextPermutation(char[] arr)
    {
        int i = arr.Length - 2;

        while (i >= 0 && arr[i] >= arr[i + 1])
            i--;

        if (i < 0)
            return false;

        int j = arr.Length - 1;

        while (arr[j] <= arr[i])
            j--;

        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        int left = i + 1, right = arr.Length - 1;

        while (left < right) {
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;

            left++;
            right--;
        }

        return true;
    }

    // Function to find all palindromic permutations.
    static List<string> allPalindromes(string s)
    {
        List<string> res = new List<string>();

        char[] arr = s.ToCharArray();
        Array.Sort(arr);

        do {
            string curr = new string(arr);

            if (IsPalindrome(curr))
                res.Add(curr);

        } while (NextPermutation(arr));

        return res;
    }

    static void Main()
    {
        string s = "abbab";

        List<string> res = allPalindromes(s);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);

            if (i + 1 < res.Count)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
// Function to check whether a string is palindrome.
function isPalindrome(str)
{
    let i = 0, j = str.length - 1;

    while (i < j) {
        if (str[i] !== str[j])
            return false;
        i++;
        j--;
    }

    return true;
}

// Function to generate the next lexicographical
// permutation.
function nextPermutation(arr)
{
    let i = arr.length - 2;

    while (i >= 0 && arr[i] >= arr[i + 1])
        i--;

    if (i === -1)
        return false;

    let j = arr.length - 1;

    while (arr[j] <= arr[i])
        j--;

    swap(arr, i, j);

    let left = i + 1, right = arr.length - 1;

    while (left < right) {
        swap(arr, left, right);
        left++;
        right--;
    }

    return true;
}

function swap(arr, i, j)
{
    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

// Function to find all palindromic permutations.
function allPalindromes(s)
{

    let res = [];

    // Sort the string to generate distinct permutations.
    let arr = s.split("").sort();

    do {

        let curr = arr.join("");

        // If the current permutation is a palindrome,
        // store it in the result.
        if (isPalindrome(curr))
            res.push(curr);

    } while (nextPermutation(arr));

    return res;
}

// Driver Code
let s = "abbab";

let res = allPalindromes(s);

process.stdout.write("[");

for (let i = 0; i < res.length; i++) {
    process.stdout.write(res[i]);

    if (i + 1 < res.length)
        process.stdout.write(", ");
}

process.stdout.write("]");

Output
[abbba, babab]

[Expected Approach] Generate Half String Permutations - O((n/2)! * n) Time and O(n) Space

The idea is to generate permutations of only the first half of the palindrome and construct the remaining half using symmetry.

Working of Approach:

  • Count the frequency of every character.
  • If more than one character has an odd frequency, no palindrome is possible.
  • Build the first half using half of every character's frequency.
  • Generate all distinct permutations of the half string.
  • Append the middle character (if any) and the reverse of the half to form complete palindromes.

Let us understand with an example:
Input: s = "abbab"

  • Count the frequency of each character: a = 2, b = 3. Since only one character (b) has an odd frequency, a palindrome is possible.
  • Construct the first half as "ab" (a/2 = 1, b/2 = 1) and store 'b' as the middle character.
  • First permutation of half = "ab" -> Reverse = "ba" -> Palindrome = "ab" + "b" + "ba" = "abbba".
  • Next permutation of half = "ba" -> Reverse = "ab" -> Palindrome = "ba" + "b" + "ab" = "babab".
  • No more permutations are possible, so return [abbba, babab].
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check if a palindrome can be formed.
bool isPalindromePossible(string &s)
{
    int n = s.size();

    if (n == 0)
        return false;

    vector<int> hash(26, 0);

    // Count the frequency of each character.
    for (char ch : s)
        hash[ch - 'a']++;

    int cnt = 0;

    // Count the characters having odd frequency.
    for (int i = 0; i < 26; i++)
    {
        if (hash[i] & 1)
            cnt++;
    }

    // For odd length, exactly one character
    // should have odd frequency.
    if ((n & 1) && cnt == 1)
        return true;

    // For even length, no character
    // should have odd frequency.
    if (n % 2 == 0 && cnt == 0)
        return true;

    return false;
}

// Function to find all possible palindromic strings.
vector<string> allPalindromes(string &s)
{

    vector<string> res;
    int n = s.size();

    // If palindrome cannot be formed,
    // return empty vector.
    if (!isPalindromePossible(s))
        return res;

    string half = "";
    vector<int> hash(26, 0);
    char mid;

    // Count the frequency of each character.
    for (char ch : s)
        hash[ch - 'a']++;

    // Construct the first half of the palindrome.
    for (int i = 0; i < 26; i++)
    {

        if (hash[i] & 1)
            mid = char(i + 'a');

        half += string(hash[i] / 2, char(i + 'a'));
    }

    // Generate all distinct permutations
    // of the first half.
    do
    {

        string cur = half;
        string rev = half;

        // Add the middle character
        // for odd length strings.
        if (n & 1)
            cur += mid;

        // Append the reverse of the first half.
        reverse(rev.begin(), rev.end());
        cur += rev;

        res.push_back(cur);

    } while (next_permutation(half.begin(), half.end()));

    return res;
}

int main()
{

    string s = "abbab";

    vector<string> res = allPalindromes(s);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];

        if (i + 1 < res.size())
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.*;

class GFG {

    // Function to check if a palindrome can be formed.
    static boolean isPalindromePossible(String s)
    {

        int n = s.length();

        if (n == 0)
            return false;

        int[] hash = new int[26];

        // Count the frequency of each character.
        for (int i = 0; i < n; i++)
            hash[s.charAt(i) - 'a']++;

        int cnt = 0;

        // Count the characters having odd frequency.
        for (int i = 0; i < 26; i++) {
            if ((hash[i] & 1) == 1)
                cnt++;
        }

        // For odd length, exactly one character
        // should have odd frequency.
        if ((n & 1) == 1 && cnt == 1)
            return true;

        // For even length, no character
        // should have odd frequency.
        if (n % 2 == 0 && cnt == 0)
            return true;

        return false;
    }

    // Function to generate the next lexicographical
    // permutation.
    static boolean nextPermutation(char[] arr)
    {

        int i = arr.length - 2;

        while (i >= 0 && arr[i] >= arr[i + 1])
            i--;

        if (i < 0)
            return false;

        int j = arr.length - 1;

        while (arr[j] <= arr[i])
            j--;

        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        int left = i + 1, right = arr.length - 1;

        while (left < right) {
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }

        return true;
    }

    // Function to find all possible palindromic strings.
    static ArrayList<String> allPalindromes(String s)
    {

        ArrayList<String> res = new ArrayList<>();
        int n = s.length();

        // If palindrome cannot be formed,
        // return empty list.
        if (!isPalindromePossible(s))
            return res;

        StringBuilder half = new StringBuilder();
        int[] hash = new int[26];
        char mid = 0;

        // Count the frequency of each character.
        for (int i = 0; i < n; i++)
            hash[s.charAt(i) - 'a']++;

        // Construct the first half of the palindrome.
        for (int i = 0; i < 26; i++) {

            if ((hash[i] & 1) == 1)
                mid = (char)(i + 'a');

            for (int j = 0; j < hash[i] / 2; j++)
                half.append((char)(i + 'a'));
        }

        char[] arr = half.toString().toCharArray();

        do {

            String firstHalf = new String(arr);
            StringBuilder cur
                = new StringBuilder(firstHalf);

            // Add the middle character
            // for odd length strings.
            if ((n & 1) == 1)
                cur.append(mid);

            // Append the reverse of the first half.
            cur.append(
                new StringBuilder(firstHalf).reverse());

            res.add(cur.toString());

        } while (nextPermutation(arr));

        return res;
    }

    public static void main(String[] args)
    {

        String s = "abbab";

        ArrayList<String> res = allPalindromes(s);

        System.out.print("[");

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));

            if (i + 1 < res.size())
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
# Function to check if a palindrome can be formed.
def isPalindromePossible(s):
    n = len(s)

    if n == 0:
        return False

    hash = [0] * 26

    # Count the frequency of each character.
    for ch in s:
        hash[ord(ch) - ord('a')] += 1

    cnt = 0

    # Count the characters having odd frequency.
    for i in range(26):
        if hash[i] & 1:
            cnt += 1

    # For odd length, exactly one character
    # should have odd frequency.
    if (n & 1) and cnt == 1:
        return True

    # For even length, no character
    # should have odd frequency.
    if n % 2 == 0 and cnt == 0:
        return True

    return False


# Function to generate the next lexicographical permutation.
def nextPermutation(arr):
    i = len(arr) - 2

    while i >= 0 and arr[i] >= arr[i + 1]:
        i -= 1

    if i < 0:
        return False

    j = len(arr) - 1

    while arr[j] <= arr[i]:
        j -= 1

    arr[i], arr[j] = arr[j], arr[i]

    left, right = i + 1, len(arr) - 1

    while left < right:
        arr[left], arr[right] = arr[right], arr[left]
        left += 1
        right -= 1

    return True


# Function to find all possible palindromic strings.
def allPalindromes(s):

    res = []
    n = len(s)

    # If palindrome cannot be formed,
    # return empty list.
    if not isPalindromePossible(s):
        return res

    hash = [0] * 26
    half = []
    mid = ""

    # Count the frequency of each character.
    for ch in s:
        hash[ord(ch) - ord('a')] += 1

    # Construct the first half of the palindrome.
    for i in range(26):

        if hash[i] & 1:
            mid = chr(i + ord('a'))

        half.extend([chr(i + ord('a'))] * (hash[i] // 2))

    # Generate all distinct permutations
    # of the first half.
    while True:

        firstHalf = "".join(half)
        cur = firstHalf

        # Add the middle character
        # for odd length strings.
        if n & 1:
            cur += mid

        # Append the reverse of the first half.
        cur += firstHalf[::-1]

        res.append(cur)

        if not nextPermutation(half):
            break

    return res


if __name__ == "__main__":

    s = "abbab"

    res = allPalindromes(s)

    print("[", end="")

    for i in range(len(res)):
        print(res[i], end="")

        if i + 1 < len(res):
            print(", ", end="")

    print("]")
C#
using System;
using System.Collections.Generic;
using System.Text;

class GFG {
    // Function to check if a palindrome can be formed.
    static bool IsPalindromePossible(string s)
    {
        int n = s.Length;

        if (n == 0)
            return false;

        int[] hash = new int[26];

        // Count the frequency of each character.
        foreach(char ch in s) hash[ch - 'a']++;

        int cnt = 0;

        // Count the characters having odd frequency.
        for (int i = 0; i < 26; i++) {
            if ((hash[i] & 1) == 1)
                cnt++;
        }

        // For odd length, exactly one character
        // should have odd frequency.
        if ((n & 1) == 1 && cnt == 1)
            return true;

        // For even length, no character
        // should have odd frequency.
        if (n % 2 == 0 && cnt == 0)
            return true;

        return false;
    }

    // Function to generate the next lexicographical
    // permutation.
    static bool NextPermutation(char[] arr)
    {
        int i = arr.Length - 2;

        while (i >= 0 && arr[i] >= arr[i + 1])
            i--;

        if (i < 0)
            return false;

        int j = arr.Length - 1;

        while (arr[j] <= arr[i])
            j--;

        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        int left = i + 1, right = arr.Length - 1;

        while (left < right) {
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }

        return true;
    }

    // Function to find all possible palindromic strings.
    static List<string> allPalindromes(string s)
    {
        List<string> res = new List<string>();
        int n = s.Length;

        // If palindrome cannot be formed,
        // return empty list.
        if (!IsPalindromePossible(s))
            return res;

        StringBuilder half = new StringBuilder();
        int[] hash = new int[26];
        char mid = '\0';

        // Count the frequency of each character.
        foreach(char ch in s) hash[ch - 'a']++;

        // Construct the first half of the palindrome.
        for (int i = 0; i < 26; i++) {
            if ((hash[i] & 1) == 1)
                mid = (char)(i + 'a');

            for (int j = 0; j < hash[i] / 2; j++)
                half.Append((char)(i + 'a'));
        }

        char[] arr = half.ToString().ToCharArray();

        do {
            string firstHalf = new string(arr);
            StringBuilder cur
                = new StringBuilder(firstHalf);

            // Add the middle character
            // for odd length strings.
            if ((n & 1) == 1)
                cur.Append(mid);

            // Append the reverse of the first half.
            char[] rev = firstHalf.ToCharArray();
            Array.Reverse(rev);
            cur.Append(new string(rev));

            res.Add(cur.ToString());

        } while (NextPermutation(arr));

        return res;
    }

    static void Main()
    {
        string s = "abbab";

        List<string> res = allPalindromes(s);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);

            if (i + 1 < res.Count)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
// Function to check if a palindrome can be formed.
function isPalindromePossible(s)
{

    let n = s.length;

    if (n === 0)
        return false;

    let hash = new Array(26).fill(0);

    // Count the frequency of each character.
    for (let ch of s)
        hash[ch.charCodeAt(0) - "a".charCodeAt(0)]++;

    let cnt = 0;

    // Count the characters having odd frequency.
    for (let i = 0; i < 26; i++) {
        if (hash[i] & 1)
            cnt++;
    }

    // For odd length, exactly one character
    // should have odd frequency.
    if ((n & 1) && cnt === 1)
        return true;

    // For even length, no character
    // should have odd frequency.
    if (n % 2 === 0 && cnt === 0)
        return true;

    return false;
}

// Function to generate the next lexicographical
// permutation.
function nextPermutation(arr)
{

    let i = arr.length - 2;

    while (i >= 0 && arr[i] >= arr[i + 1])
        i--;

    if (i < 0)
        return false;

    let j = arr.length - 1;

    while (arr[j] <= arr[i])
        j--;

    [arr[i], arr[j]] = [ arr[j], arr[i] ];

    let left = i + 1, right = arr.length - 1;

    while (left < right) {
        [arr[left], arr[right]] = [ arr[right], arr[left] ];
        left++;
        right--;
    }

    return true;
}

// Function to find all possible palindromic strings.
function allPalindromes(s)
{

    let res = [];
    let n = s.length;

    // If palindrome cannot be formed,
    // return empty array.
    if (!isPalindromePossible(s))
        return res;

    let hash = new Array(26).fill(0);
    let half = [];
    let mid = "";

    // Count the frequency of each character.
    for (let ch of s)
        hash[ch.charCodeAt(0) - "a".charCodeAt(0)]++;

    // Construct the first half of the palindrome.
    for (let i = 0; i < 26; i++) {

        if (hash[i] & 1)
            mid = String.fromCharCode(i
                                      + "a".charCodeAt(0));

        for (let j = 0; j < Math.floor(hash[i] / 2); j++)
            half.push(
                String.fromCharCode(i + "a".charCodeAt(0)));
    }

    // Generate all distinct permutations
    // of the first half.
    do {

        let firstHalf = half.join("");
        let cur = firstHalf;

        // Add the middle character
        // for odd length strings.
        if (n & 1)
            cur += mid;

        // Append the reverse of the first half.
        cur += [...firstHalf ].reverse().join("");

        res.push(cur);

    } while (nextPermutation(half));

    return res;
}

// Driver Code
let s = "abbab";

let res = allPalindromes(s);

process.stdout.write("[");

for (let i = 0; i < res.length; i++) {
    process.stdout.write(res[i]);

    if (i + 1 < res.length)
        process.stdout.write(", ");
}

process.stdout.write("]");

Output
[abbba, babab]
Comment