Length of the Longest Palindrome

medium

By - Aman Pareek

Last Updated - 02/09/2024

Problem Statement

You are given a string s composed of lowercase and/or uppercase English letters. Your task is to determine the length of the longest palindrome that can be constructed using the characters from the string. Note that the characters are case-sensitive; for example, 'a' and 'A' are considered different characters and do not match each other.

Example 1

Input: s = "abccccdd"

Output: 7

Example 2

Input: s = "a"

Output: 1

Solution 1: Frequency Count Approach

function longestPalindromeUsingFrequency(s) {
    const freq = {};
    let length = 0;
    let hasOdd = false;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const count of Object.values(freq)) {
        length += Math.floor(count / 2) * 2;
        if (count % 2 === 1) {
            hasOdd = true;
        }
    }

    return length + (hasOdd ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeUsingFrequency(s1);  //output: 7 

const s2 = "a";
longestPalindromeUsingFrequency(s2);  //output: 1 

Solution 2: Using a Set to Track Odd Frequencies

function longestPalindromeWithSet1(s) {
    const oddSet = new Set();
    
    for (const char of s) {
        if (oddSet.has(char)) {
            oddSet.delete(char);
        } else {
            oddSet.add(char);
        }
    }

    return s.length - oddSet.size + (oddSet.size > 0 ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeWithSet1(s1);  //output: 7 

const s2 = "a";
longestPalindromeWithSet1(s2);  //output: 1 

Solution 3: HashMap with Conditional Check

function longestPalindromeWithSet(s) {
    const oddSet = new Set();
    
    for (const char of s) {
        if (oddSet.has(char)) {
            oddSet.delete(char);
        } else {
            oddSet.add(char);
        }
    }

    return s.length - oddSet.size + (oddSet.size > 0 ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeWithSet(s1);  //output: 7 

const s2 = "a";
longestPalindromeWithSet(s2);  //output: 1 

Solution 4: Array-Based Frequency Count

function longestPalindromeUsingHashMap(s) {
    const freq = {};
    let length = 0;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const count of Object.values(freq)) {
        length += Math.floor(count / 2) * 2;
    }

    return length + (length < s.length ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeUsingHashMap(s1);  //output: 7 

const s2 = "a";
longestPalindromeUsingHashMap(s2);  //output: 1 

Solution 5: Using Frequency Object and Array

function longestPalindromeFreqArray(s) {
    const freq = {};
    const charArray = [];
    let length = 0;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const char in freq) {
        charArray.push(freq[char]);
    }

    for (const count of charArray) {
        length += Math.floor(count / 2) * 2;
    }

    return length + (length < s.length ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeFreqArray(s1);  //output: 7 

const s2 = "a";
longestPalindromeFreqArray(s2);  //output: 1 

Solution 6: Frequency Count with Object.keys

function longestPalindromeFromKeys(s) {
    const freq = {};
    let length = 0;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const char of Object.keys(freq)) {
        length += Math.floor(freq[char] / 2) * 2;
    }

    return length + (length < s.length ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeFromKeys(s1);  //output: 7 

const s2 = "a";
longestPalindromeFromKeys(s2);  //output: 1 

Solution 7: Using Map for Character Frequencies

function longestPalindromeWithMap(s) {
    const freq = new Map();
    let length = 0;

    for (const char of s) {
        freq.set(char, (freq.get(char) || 0) + 1);
    }

    for (const count of freq.values()) {
        length += Math.floor(count / 2) * 2;
    }

    return length + (length < s.length ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeWithMap(s1);  //output: 7 

const s2 = "a";
longestPalindromeWithMap(s2);  //output: 1 

Solution 8: Advanced Frequency Counting with Iteration

function longestPalindromeAdvancedCount(s) {
    const freq = {};
    let length = 0;
    let oddCount = 0;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const count of Object.values(freq)) {
        length += Math.floor(count / 2) * 2;
        if (count % 2 === 1) {
            oddCount++;
        }
    }

    return length + (oddCount > 0 ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeAdvancedCount(s1);  //output: 7 

const s2 = "a";
longestPalindromeAdvancedCount(s2);  //output: 1 

Solution 9: Using Character Frequency Map and Aggregation

function longestPalindromeMapAggregation(s) {
    const freq = new Map();
    let length = 0;
    let hasOddFrequency = false;

    for (const char of s) {
        freq.set(char, (freq.get(char) || 0) + 1);
    }

    for (const count of freq.values()) {
        length += Math.floor(count / 2) * 2;
        if (count % 2 === 1) {
            hasOddFrequency = true;
        }
    }

    return length + (hasOddFrequency ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeMapAggregation(s1);  //output: 7 

const s2 = "a";
longestPalindromeMapAggregation(s2);  //output: 1 

Solution 10: Iterative Count with Central Character Check

function longestPalindromeWithCentralChar(s) {
    const freq = {};
    let length = 0;
    let hasOdd = false;

    for (const char of s) {
        freq[char] = (freq[char] || 0) + 1;
    }

    for (const count of Object.values(freq)) {
        length += Math.floor(count / 2) * 2;
        if (count % 2 === 1) {
            hasOdd = true;
        }
    }

    return length + (hasOdd ? 1 : 0);
} 

const s1 = "abccccdd";
longestPalindromeWithCentralChar(s1);  //output: 7 

const s2 = "a";
longestPalindromeWithCentralChar(s2);  //output: 1