Palindrome Permutation or Anagram (original) (raw)
Last Updated : 14 Apr, 2026
Given a string **s, check if the characters of the given string can be rearranged to form a palindrome.
**Input: s = "geeksgeeks"
**Output: True
**Explanation: The string can be converted into a palindrome: kgeesseegk**Input: s = "geeksforgeeks "
**Output: False
**Explanation: More than one character has odd frequency, so it cannot form a palindrome.
Table of Content
- [Naive Approach] Using Two Loop - O(n^2) Time and O(1)
- [Better Approach-1] Using Frequency Count - O(n) Time and O(1) Space
- [Better Approach-2] Using Bit Manipulation (Bitmask) - O(n) Time and O(1) Space
**Common Idea used in all approaches: A set of characters can form a palindrome if at most one character occurs an odd number of times and all characters occur an even number of times.
[Naive Approach] Using Two Loop - O(n^2) Time and O(1)
The idea is to count the frequency of each character by comparing it with every other character using nested loops. A string can form a palindrome if at most one character has an odd frequency.
- For each character in the string, compare it with all other characters to count its frequency.
- Use two loops (nested) to calculate frequency for every character.
- While counting, track how many characters have odd frequency.
- If more than one character has an odd count, the string cannot form a palindrome.
- If at most one character has an odd count, the string can form a palindrome. C++ `
#include #include using namespace std;
bool canFormPalindrome(string &s) { int odd = 0;
// Count frequency using two loops
for (int i = 0; s[i]; i++) {
int count = 0;
for (int j = 0; s[j]; j++) {
if (s[i] == s[j])
count++;
}
if (count % 2 != 0)
odd++;
if (odd > 1)
return false;
}
return true;}
int main() { string s1 = "geeksgeeks"; string s2 = "geeksforgeeks";
cout << (canFormPalindrome(s1)
? "True\n" : "False\n");
cout << (canFormPalindrome(s2)
? "True\n" : "False\n");
return 0;}
Java
class GfG {
static boolean canFormPalindrome(String s)
{
int odd = 0;
// Count frequency using two loops
for (int i = 0; i < s.length(); i++) {
int count = 0;
for (int j = 0; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j))
count++;
}
if (count % 2 != 0)
odd++;
if (odd > 1)
return false;
}
return true;
}
public static void main(String[] args)
{
System.out.println(canFormPalindrome("geeksgeeks")
? "True" : "False");
System.out.println(canFormPalindrome("geeksforgeeks")
? "True" : "False");
}}
Python
def canFormPalindrome(s): odd = 0
# Count frequency using two loops
for i in range(len(s)):
count = 0
for j in range(len(s)):
if s[i] == s[j]:
count += 1
if count % 2 != 0:
odd += 1
if odd > 1:
return False
return Trueif name == "main": print("True" if canFormPalindrome("geeksgeeks") else "False") print("True" if canFormPalindrome("geeksforgeeks") else "False")
C#
using System;
class GfG {
static bool canFormPalindrome(string s)
{
int odd = 0;
// Count frequency using two loops
for (int i = 0; i < s.Length; i++) {
int count = 0;
for (int j = 0; j < s.Length; j++) {
if (s[i] == s[j])
count++;
}
if (count % 2 != 0)
odd++;
if (odd > 1)
return false;
}
return true;
}
static void Main(string[] args)
{
Console.WriteLine(CanFormPalindrome("geeksgeeks")
? "True" : "False");
Console.WriteLine(CanFormPalindrome("geeksforgeeks")
? "True" : "False");
}}
JavaScript
function canFormPalindrome(s) { let odd = 0;
// Count frequency using two loops
for (let i = 0; i < s.length; i++) {
let count = 0;
for (let j = 0; j < s.length; j++) {
if (s[i] === s[j])
count++;
}
if (count % 2 !== 0)
odd++;
if (odd > 1)
return false;
}
return true;}
// Driver code console.log(canFormPalindrome("geeksgeeks") ? "True" : "False"); console.log(canFormPalindrome("geeksforgeeks") ? "True" : "False");
`
[Better Approach-1] Using Frequency Count - O(n) Time and O(1) Space
First, traverse the string and store the frequency of each character in a count array. Then, check the count array to see how many characters have odd frequency. If more than one character has an odd count, it is not possible to form a palindrome; otherwise, it is possible.
Dry run for s = "geeksgeeks":
- Traverse "geeksgeeks" and count characters i.e, g:2, e:4, k:2, s:2.
- Check each count, all characters appear even number of times.
- Odd frequency count = 0 (no character has odd occurrence).
- Since at most one odd is allowed and here none exist.
- So, palindrome rearrangement is possible, return true. C++ `
#include #include using namespace std;
bool canFormPalindrome(string &s) { int count[256] = {0};
// Count frequency of characters
for (int i = 0; s[i]; i++)
count[s[i]]++;
int odd = 0;
// Count odd frequencies
for (int i = 0; i < 256; i++) {
if (count[i] % 2 != 0)
odd++;
if (odd > 1)
return false;
}
return true;}
int main() { string s1 = "geeksgeeks"; string s2 = "geeksforgeeks";
cout << (canFormPalindrome(s1)
? "True\n" : "False\n");
cout << (canFormPalindrome(s2)
? "True\n" : "False\n");
return 0;}
Java
class GfG {
static boolean canFormPalindrome(String s)
{
int[] count = new int[256];
// frequency count
for (int i = 0; i < s.length(); i++)
count[s.charAt(i)]++;
int odd = 0;
// check odd frequencies
for (int i = 0; i < 256; i++) {
if (count[i] % 2 != 0)
odd++;
if (odd > 1)
return false;
}
return true;
}
public static void main(String[] args)
{
System.out.println(canFormPalindrome("geeksgeeks")
? "True" : "False");
System.out.println(canFormPalindrome("geeksforgeeks")
? "True" : "False");
}}
Python
def canFormPalindrome(s): count = [0] * 256
# frequency count
for ch in s:
count[ord(ch)] += 1
odd = 0
# check odd frequencies
for c in count:
if c % 2 != 0:
odd += 1
if odd > 1:
return False
return Trueif name == "main": print("True" if canFormPalindrome("geeksgeeks") else "False") print("True" if canFormPalindrome("geeksforgeeks") else "False")
C#
using System;
class GfG {
static bool CanFormPalindrome(string s)
{
int[] count = new int[256];
// frequency count
for (int i = 0; i < s.Length; i++)
count[s[i]]++;
int odd = 0;
// check odd frequencies
for (int i = 0; i < 256; i++) {
if (count[i] % 2!= 0)
odd++;
if (odd > 1)
return false;
}
return true;
}
static void Main(string[] args)
{
Console.WriteLine(CanFormPalindrome("geeksgeeks")
? "True" : "False");
Console.WriteLine(CanFormPalindrome("geeksforgeeks")
? "True" : "False");
}}
JavaScript
function canFormPalindrome(s) { let count = Array(256).fill(0);
// frequency count
for (let ch of s) {
count[ch.charCodeAt(0)] += 1;
}
let odd = 0;
// check odd frequencies
for (let c of count) {
if (c % 2!== 0) {
odd += 1;
}
if (odd > 1) {
return false;
}
}
return true;}
// Driver code console.log(canFormPalindrome("geeksgeeks") ? "True" : "False"); console.log(canFormPalindrome("geeksforgeeks") ? "True" : "False");
`
[Better Approach-2] Using Bit Manipulation (Bitmask) - O(n) Time and O(1) Space
The idea is to track the frequency of characters using a bitmask instead of counting each one separately. If character set is limited (say only lowercase, i.e., 26 characters), a single integer's bits (total 32 bits typically) can be used to track odd frequencies.
- For every character in the string, toggle its corresponding bit using XOR.
- If a character appears an even number of times, its bit becomes 0.
- If a character appears an odd number of times, its bit becomes 1.
- After processing all characters, check the final bitmask.
- If the bitmask has at most one bit set (i.e., at most one character has odd frequency), the string can form a palindrome.
- Otherwise, the string cannot form a palindrome. C++ `
#include #include using namespace std;
bool canFormPalindrome(string &s) { int mask = 0;
// toggle bits
for (int i = 0; s[i]; i++) {
int bit = s[i] - 'a';
mask ^= (1 << bit);
}
// check at most one bit set
return (mask == 0) || (mask & (mask - 1)) == 0;}
int main() { string s1 = "geeksgeeks"; string s2 = "geeksforgeeks";
cout << (canFormPalindrome(s1)
? "True\n" : "False\n");
cout << (canFormPalindrome(s2)
? "True\n" : "False\n");
return 0;}
Java
class GfG {
static boolean canFormPalindrome(String s)
{
int mask = 0;
// toggle bits
for (int i = 0; i < s.length(); i++) {
int bit = s.charAt(i) - 'a';
mask ^= (1 << bit);
}
// check at most one bit set
return (mask == 0) || ((mask & (mask - 1)) == 0);
}
public static void main(String[] args)
{
System.out.println(canFormPalindrome("geeksgeeks") ? "True" : "False");
System.out.println(canFormPalindrome("geeksforgeeks") ? "True" : "False");
}}
Python
def canFormPalindrome(s): mask = 0
# toggle bits
for ch in s:
bit = ord(ch) - ord('a')
mask ^= (1 << bit)
# check at most one bit set
return mask == 0 or (mask & (mask - 1)) == 0if name == "main": print("True" if canFormPalindrome("geeksgeeks") else "False") print("True" if canFormPalindrome("geeksforgeeks") else "False")
C#
using System;
class GfG {
public static bool CanFormPalindrome(string s)
{
int mask = 0;
// toggle bits
for (int i = 0; i < s.Length; i++) {
int bit = s[i] - 'a';
mask ^= (1 << bit);
}
// check at most one bit set
return (mask == 0) || ((mask & (mask - 1)) == 0);
}
static void Main(string[] args)
{
Console.WriteLine(CanFormPalindrome("geeksgeeks") ? "True" : "False");
Console.WriteLine(CanFormPalindrome("geeksforgeeks") ? "True" : "False");
}}
JavaScript
function canFormPalindrome(s) { let mask = 0;
// toggle bits
for (let i = 0; i < s.length; i++) {
let bit = s.charCodeAt(i) - 'a'.charCodeAt(0);
mask ^= (1 << bit);
}
// check at most one bit set
return mask === 0 || (mask & (mask - 1)) === 0;}
// Driver code console.log(canFormPalindrome("geeksgeeks") ? "True" : "False"); console.log(canFormPalindrome("geeksforgeeks") ? "True" : "False");
`