1. 程式人生 > 其它 >【LeetCode】159.至多包含兩個不同字元的最長子串

【LeetCode】159.至多包含兩個不同字元的最長子串

159.至多包含兩個不同字元的最長子串

知識點:字串;滑動視窗

題目描述

給定一個字串 s ,找出 至多 包含兩個不同字元的最長子串 t 。

注意:

對於 t 中重複字元,我們尋找的子字串中該字元數量必須不少於 t 中該字元數量。
如果 s 中存在這樣的子串,我們保證它是唯一的答案。

示例
示例 1:
輸入: "eceba"
輸出: 3
解釋: t 是 "ece",長度為3。


示例 2:
輸入: "ccaabbb"
輸出: 5
解釋: t 是 "aabbb",長度為5。


解法一:滑動視窗

這其實也是滑動視窗的一道典型題目
剛看題目,最長子串,其實應該自然的想到滑動視窗。 最大,往往都是right向右移動尋找最優解,然後破壞了條件,然後left移動,縮小視窗,繼續形成可行解;
對應到這道題目:
1.right右移,試圖尋找一個最長視窗,直至破壞了條件,也就是包含了第三個字元

步驟一我們需要在視窗內含有第三個字元的時候停下來,自然想到了雜湊表,當雜湊表長度為3的時候,證明第三個字元出現了,這時候就需要去移動左視窗了

2.left開始移動,縮小視窗

left移動到哪個位置呢?我們的目的是讓left移動後窗口重新滿足條件,也就是隻有兩個字元,所以需要把一個字元移出去,也就是移到索引最小的位置+1處
例如例1,需要移動到c後面,而不能移動到第2個e後面,所以雜湊表的value值應該是字元c最後一次出現的索引,而我們要的就是找到這兩個字元誰的索引小,所以可以直接對其value形成的list進行排序,取第一個即可。

在這個過程中不斷的更新最大視窗值

class resolution:
    def getlongestsubstring(self, s):
        hashtable = {}
        max_len = left = 0
        for i, cur_str in enumerate(s):
            if len(hashtable) < 3:
                hashtable[cur_str] = i   
            if len(hashtable) == 3:  
                index = sorted(hashtable.values())[0]  # 在雜湊表裡的最小索引,left移動,將這個字元移出視窗
                left = index + 1
                hashtable.pop(s[index])  # 移出雜湊表
            max_len = max(max_len, i-left+1)
        return max_len