【LeetCode 簡單題】91-最長迴文串
阿新 • • 發佈:2018-11-19
宣告:
今天是第91道題。給定一個包含大寫字母和小寫字母的字串,找到可由這些字母構造成的最長的迴文串。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除
(手動比心ღ( ´・ᴗ・` ))
正文
題目:給定一個包含大寫字母和小寫字母的字串,找到可由這些字母構造成的最長的迴文串。在構造過程中,請注意區分大小寫。比如 "Aa"
不能當做一個迴文字串。
注意:
假設字串的長度不會超過 1010。
示例 1:
輸入: "abccccdd" 輸出: 7 解釋: 我們可以構造的最長的迴文串是"dccaccd", 它的長度是 7
解法1。觀察得知,構成迴文串肯定是由偶數字符和1個奇數字符構成的,所以只要計算出s裡有幾個出現頻次為奇數的字元,然後用s的長度減去奇數字符個數再加1(減去了頻次為奇數的字元剩下都是偶數次的字元了,奇數字符也變偶數字符了),考慮一種特殊情況,如果全是偶數字符就直接返回s的長度,程式碼如下。
執行用時: 48 ms, 在Longest Palindrome的Python3提交中擊敗了94.29% 的使用者
- 偶數字符:毋庸置疑,肯定可以都出現在最長迴文串裡
- 奇數字符:奇數字符頻數-1後變為偶數字符放到迴文串裡,最後還可以再加上1個奇數字符放中間
class Solution: def longestPalindrome(self, s): """ :type s: str :rtype: int """ odd_cnt = 0 for i in set(i): # 注意這裡一定要去重,避免重複計數 if s.count(i) % 2 != 0: odd_cnt += 1 if odd_cnt == 0: return len(s) return len(s)-odd_cnt+1 # 奇數字符頻次都-1,累加起來就是-odd_cnt,最後+1是還能從減去的這些奇數字符裡挑1個出來放中間 # 上述程式碼的優化版本 count = 0 for i in set(s): if s.count(i) % 2 == 0: count += s.count(i) else: count += (s.count(i)//2)*2 # 此處很妙,奇數字符的頻次若>2的話,通過除2取餘再乘2可以保留歐偶數個字元 if res < len(s): res += 1 return res
解法2。大致思路和上面差不多,就是用了字典統計出每個字元的出現頻數並分為奇數和偶數,然後返回最長迴文串的長度,程式碼如下。
執行用時: 64 ms, 在Longest Palindrome的Python3提交中擊敗了22.50% 的使用者
class Solution:
def longestPalindrome(self, s):
"""
:type s: str
:rtype: int
"""
from collections import Counter
dict_s = Counter(s)
even = []
odd = []
for k,v in dict_s.items():
if v%2 == 0:
even.append(v)
else:
odd.append(v)
if len(odd) != 0: # 也就是說s裡面有奇數字符
max_odd = max(odd)
odd.remove(max_odd)
return max_odd + sum(even) + sum(odd) - len(odd)
else:
return sum(even)
結尾
解法1:https://www.jianshu.com/p/ebdd12da8c3c
解法2:LeetCode