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/