If all letters in a string have an even count, with the exception of no more than one, you can always reorganize them into a palindrome. My solution is a bit longer than the others, because I tried to minimize the overhead of loop performance with functions and unnecessary array creation.
aaaabbbb => aabbbbaa aaaabbbbc => aabbcbbaa function isPalindromable(str) { var map = getCharCount(str); var nonPairs = 0; for (var char in charMap) { if (charMap[char] % 2 != 0) nonPairs++; if (nonPairs > 1) return false; } return true; } function getCharCount(str) {
If you like one liner (not so fast, but elegant)
function isPalindromable(str) { var charMap = getCharCountMap(str); return Object.keys(charMap).filter(char => charMap[char] %2 > 0).length <= 1; } function getCharCountMap(str) { return str.split('').reduce((prev, cur) => (prev[cur] = ++prev[cur] || 1, prev) , {}) }
Performance editing
I compared three solutions. Mine was the slowest when the strings were short, and faster for longer strings. However, a friend at work came up with a solution that would ultimately be the fastest, perhaps because it has only one cycle, but does not need to be sorted. http://jsperf.com/can-string-be-made-into-palindrome/2
function canBePalindromeReplace(string) { var oddCount = 0; while(string.length > 0) { var char = string.charAt(0); var stringLength = string.length; string = string.replace(new RegExp(char, 'g'), ''); var diff = stringLength - string.length; if((diff % 2) != 0) { oddCount++; if(oddCount > 1) { return false; } } } return true; }
source share