Print all palindrome permutations of a string
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++ 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 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 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# 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 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)