Given a string s
, write a function to return all the possible palindromic permutations (without duplicates) of s
. Return an empty list if no palindromic permutation could be formed.
For example:
Input: s = "aabb" Output: ["abba","baab"]
Input: s = "abc" Output: []
Input: s = "a" Output: ["a"]
Input: s = "" Output: [""]
Explain your approach, including time and space complexity. Consider edge cases like empty strings, single-character strings, and strings for which no palindrome can be constructed.
Given a string s
, return all the possible palindromic permutations (without duplicates) of s
. Return an empty list if no palindromic permutation could be formed.
Example 1:
Input: s = "aabb"
Output: ["abba","baab"]
Example 2:
Input: s = "abc"
Output: []
A brute force approach would be to generate all possible permutations of the input string and then check each permutation to see if it's a palindrome. If it is a palindrome, we add it to our result set (using a Set
to avoid duplicates). However, this is highly inefficient.
import java.util.*;
public class Solution {
public List<String> generatePalindromes(String s) {
Set<String> result = new HashSet<>();
List<String> permutations = new ArrayList<>();
char[] chars = s.toCharArray();
permute(chars, 0, permutations);
for (String perm : permutations) {
if (isPalindrome(perm)) {
result.add(perm);
}
}
return new ArrayList<>(result);
}
private void permute(char[] chars, int l, List<String> permutations) {
if (l == chars.length) {
permutations.add(new String(chars));
return;
}
for (int i = l; i < chars.length; i++) {
swap(chars, l, i);
permute(chars, l + 1, permutations);
swap(chars, l, i); // backtrack
}
}
private void swap(char[] chars, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
private boolean isPalindrome(String s) {
int left = 0;
int right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
}
O(n! * n), where n is the length of the string. O(n!) for generating all permutations and O(n) for checking if each permutation is a palindrome.
O(n! + n), where O(n!) is for storing all possible permutations and O(n) to store the string.
import java.util.*;
public class Solution {
public List<String> generatePalindromes(String s) {
Map<Character, Integer> counts = new HashMap<>();
for (char c : s.toCharArray()) {
counts.put(c, counts.getOrDefault(c, 0) + 1);
}
int oddCount = 0;
Character oddChar = null;
for (Map.Entry<Character, Integer> entry : counts.entrySet()) {
if (entry.getValue() % 2 != 0) {
oddCount++;
oddChar = entry.getKey();
}
}
if (oddCount > 1) {
return new ArrayList<>(); // No palindrome possible
}
String half = buildHalf(counts);
List<String> result = new ArrayList<>();
permuteUnique(half.toCharArray(), 0, result, oddChar);
return result;
}
private String buildHalf(Map<Character, Integer> counts) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<Character, Integer> entry : counts.entrySet()) {
char c = entry.getKey();
int count = entry.getValue() / 2;
for (int i = 0; i < count; i++) {
sb.append(c);
}
}
return sb.toString();
}
private void permuteUnique(char[] chars, int l, List<String> result, Character oddChar) {
if (l == chars.length) {
String half = new String(chars);
String palindrome = half + (oddChar == null ? "" : oddChar) + new StringBuilder(half).reverse().toString();
result.add(palindrome);
return;
}
Set<Character> seen = new HashSet<>();
for (int i = l; i < chars.length; i++) {
if (seen.add(chars[i])) {
swap(chars, l, i);
permuteUnique(chars, l + 1, result, oddChar);
swap(chars, l, i); // backtrack
}
}
}
private void swap(char[] chars, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}
O((n/2)! * n), where n is the length of the string. Building the half string takes O(n). Generating unique permutations of the half string which has a length of approximately n/2 takes O((n/2)!). Each permutation requires O(n) to create the full palindrome string.
O(n), where n is the length of the string. O(n) space for storing character counts and other strings.
[aaaa]