3種解法 - 計算最長迴文串

題目

給定一個包含大寫字母和小寫字母的字符串,找到通過這些字母構造成的最長的迴文串。

在構造過程中,請注意區分大小寫。比如 “Aa” 不能當做一個迴文字符串。

注意:
假設字符串的長度不會超過 1010。

示例 1:

輸入:
“abccccdd”

輸出:
7

解釋:
我們可以構造的最長的迴文串是"dccaccd", 它的長度是 7。


解法一(字典)

思路:可以構建迴文串就相當於構建左右對稱的字符,但是最中間可以出現一個字符,因此對於奇數可以進行多一個字符。
即題目的思路就是統計字符中可以構建最多的偶數個數,如果是奇數則減一即爲最大的偶數,如果是偶數則本身即爲最大的偶數。

  1. 統計每個字符的個數
  2. 對字符個數進行奇偶判斷,偶數直接累加,奇數標記並減一後累加
  3. 如果出現過奇數,則整體加1
  • 時間複雜度:O(n)
  • 空間複雜度:O(n)
public class Solution {
	//[email protected]
    public int LongestPalindrome(string s) {
        int cnt = 0;
        Dictionary<char,int> dict = new Dictionary<char,int>();
        foreach(char item in s)
        {//統計每個字符個數
            if(dict.ContainsKey(item))
            {
                dict[item] ++;
            }
            else
            {
                dict.Add(item,1);
            }
        }
        bool flag = false;
        foreach(int item in dict.Values)
        {
            if((item & 1) == 1)
            {//奇數
                cnt += item - 1;
                flag = true;
            }
            else
            {//偶數
                cnt += item;
            }
        }
        cnt += flag?1:0;
        return cnt;
    }
}

解法二(固定數組)

思路:前面解法是最常規或者第一反應的做法,現在使用固定數組保存字符個數,減少字典hash的計算,儘管消耗也不大。

  1. 申請固定長度數組:58 = ‘z’ - ‘A’ + 1,或者可以直接申請128(ascii)個,則不用進行減’A’的計算
  2. 統計字符個數,利用了除法取整進行了奇數過濾,即3/2 ==(int)1.5 == 1
  3. 本解法判斷奇數方法跟前面不同,是通過整體字符長度大於當前求和長度來判斷。
  • 時間複雜度:O(n)
  • 空間複雜度:O(1)
public class Solution {
	//[email protected]
    public int LongestPalindrome(string s) {
        int cnt = 0;
        int [] arrChar = new int[58];
        foreach(char item in s)
        {//統計每個字符個數
            arrChar[item - 'A'] ++;
        }        
        foreach(int item in arrChar)
        {//字符計數
            cnt += (int)(item / 2) * 2;
        }
        cnt += cnt < s.Length?1:0;
        return cnt;
    }
}

解法三(Pythonic)

思路:用Python的內置函數進行運算來簡化程序

  1. 使用collections.Counter函數,對每個字符出現次數進行統計
  2. 使用sum函數,對所有次數裏的偶數求和
  3. 如果有奇數存在,則整體加1
class Solution:
	#[email protected]
    def longestPalindrome(self, s: str) -> int:
        cnt = sum([v-1 if v%2==1 else v for v in collections.Counter(s).values()])
        return cnt + 1 if cnt < len(s) else cnt

在這裏插入圖片描述
截圖從上往下分別是:解法2,1,3
解法2執行出錯,是開始申請的空間是26,忽略了大小寫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章