Check if any anagram of a string is palindrome or not in Python

An anagram is a rearrangement of the characters of a word or phrase to generate a new word, using all the original characters exactly once. For example, thing and night are anagrams of each other. A palindrome is a word or phrase that reads the same forward and backward, like madam or racecar.

In this article, we'll check if any anagram of a string can form a palindrome. The key insight is that for a string to have a palindromic anagram, at most one character can have an odd frequency.

Algorithm Logic

For a palindrome to be possible ?

  • All characters must have even frequencies, OR
  • Exactly one character has odd frequency (this becomes the middle character)

Example Scenarios

Scenario 1: Palindrome Possible

Input: "ivicc"
Character frequencies: i=2, v=1, c=2
Only one character (v) has odd frequency ? Palindrome possible: "civic"

Scenario 2: Palindrome Not Possible

Input: "abc"
Character frequencies: a=1, b=1, c=1
Three characters have odd frequencies ? Palindrome not possible

Using Counter to Check Character Frequencies

We can use Python's Counter from the collections module to count character frequencies ?

from collections import Counter

def can_form_palindrome(s):
    char_count = Counter(s)
    odd_count = sum(1 for count in char_count.values() if count % 2 != 0)
    return odd_count <= 1

# Test with "carrace"
result1 = can_form_palindrome("carrace")
print(f"Can 'carrace' form palindrome: {result1}")

# Show character frequencies
print(f"Character frequencies: {dict(Counter('carrace'))}")
Can 'carrace' form palindrome: True
Character frequencies: {'c': 2, 'a': 2, 'r': 2, 'e': 1}

Testing with Different Inputs

Let's test multiple cases to see how the algorithm works ?

from collections import Counter

def can_form_palindrome(s):
    char_count = Counter(s)
    odd_count = sum(1 for count in char_count.values() if count % 2 != 0)
    return odd_count <= 1

# Test cases
test_cases = ["carrace", "abc", "aab", "aabb", "racecar"]

for test in test_cases:
    result = can_form_palindrome(test)
    frequencies = dict(Counter(test))
    print(f"'{test}' ? {result} | Frequencies: {frequencies}")
'carrace' ? True | Frequencies: {'c': 2, 'a': 2, 'r': 2, 'e': 1}
'abc' ? False | Frequencies: {'a': 1, 'b': 1, 'c': 1}
'aab' ? True | Frequencies: {'a': 2, 'b': 1}
'aabb' ? True | Frequencies: {'a': 2, 'b': 2}
'racecar' ? True | Frequencies: {'r': 2, 'a': 2, 'c': 2, 'e': 1}

Alternative Approach Using Set

We can also use a set to track characters with odd frequencies ?

def can_form_palindrome_set(s):
    odd_chars = set()
    
    for char in s:
        if char in odd_chars:
            odd_chars.remove(char)  # Even count now
        else:
            odd_chars.add(char)     # Odd count now
    
    return len(odd_chars) <= 1

# Test the alternative approach
test_string = "carrace"
result = can_form_palindrome_set(test_string)
print(f"Using set approach: '{test_string}' ? {result}")
Using set approach: 'carrace' ? True

Comparison of Methods

Method Time Complexity Space Complexity Readability
Counter O(n) O(k) High
Set O(n) O(k) Medium

where n is string length and k is number of unique characters

Conclusion

To check if any anagram of a string can form a palindrome, count character frequencies. At most one character should have an odd frequency. The Counter approach is more readable, while the set approach is more memory-efficient for tracking odd frequencies.

Updated on: 2026-03-25T14:18:05+05:30

636 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements