Given a string, determine if a permutation of the string could form a palindrome.html
Example 1:ide
Input: Output: false"code"
Example 2:post
Input: Output: true"aab"
Example 3:url
Input: Output: true"carerac"
Hint:spa
这道题让咱们判断一个字符串的全排列有没有是回文字符串的,那么根据题目中的提示,咱们分字符串的个数是奇偶的状况来讨论,若是是偶数的话,因为回文字符串的特性,每一个字母出现的次数必定是偶数次,当字符串是奇数长度时,只有一个字母出现的次数是奇数,其他均为偶数,那么利用这个特性咱们就能够解题,咱们创建每一个字母和其出现次数的映射,而后咱们遍历 HashMap,统计出现次数为奇数的字母的个数,那么只有两种状况是回文数,第一种是没有出现次数为奇数的字母,再一个就是字符串长度为奇数,且只有一个出现次数为奇数的字母,参见代码以下:code
解法一:orm
class Solution { public: bool canPermutePalindrome(string s) { unordered_map<char, int> m; int cnt = 0; for (auto a : s) ++m[a]; for (auto a : m) { if (a.second % 2 == 1) ++cnt; } return cnt == 0 || (s.size() % 2 == 1 && cnt == 1); } };
那么咱们再来看一种解法,这种方法用到了一个 HashSet,咱们遍历字符串,若是某个字母不在 HashSet 中,咱们加入这个字母,若是字母已经存在,咱们删除该字母,那么最终若是 HashSet 中没有字母或是只有一个字母时,说明是回文串,参见代码以下:htm
解法二:blog
class Solution { public: bool canPermutePalindrome(string s) { unordered_set<char> st; for (auto a : s) { if (!st.count(a)) st.insert(a); else st.erase(a); } return st.empty() || st.size() == 1; } };
再来看一种 bitset 的解法,这种方法也很巧妙,咱们创建一个 256 大小的 bitset,每一个字母根据其 ASCII 码值的不一样都有其对应的位置,而后咱们遍历整个字符串,遇到一个字符,就将其对应的位置的二进制数 flip 一下,就是0变1,1变0,那么遍历完成后,全部出现次数为偶数的对应位置还应该为0,而出现次数为奇数的时候,对应位置就为1了,那么咱们最后只要统计1的个数,就知道出现次数为奇数的字母的个数了,只要个数小于2就是回文数,参见代码以下:ip
解法三:
class Solution { public: bool canPermutePalindrome(string s) { bitset<256> b; for (auto a : s) { b.flip(a); } return b.count() < 2; } };
相似题目:
参考资料:
https://leetcode.com/problems/palindrome-permutation/