76.最小覆蓋子串 Golang實現

wochh發表於2024-09-23

題目描述:

給你一個字串 s 、一個字串 t 。返回 s 中涵蓋 t 所有字元的最小子串。如果 s 中不存在涵蓋 t 所有字元的子串,則返回空字串 "" 。
注意:
對於 t 中重複字元,我們尋找的子字串中該字元數量必須不少於 t 中該字元數量。
如果 s 中存在這樣的子串,我們保證它是唯一的答案。

示例 1:
輸入:s = "ADOBECODEBANC", t = "ABC"
輸出:"BANC"
解釋:最小覆蓋子串 "BANC" 包含來自字串 t 的 'A'、'B' 和 'C'。

題目分析:
看到這類最長最短子串等,則首選滑動視窗方法。按照滑動視窗的方法,重點應該是確定滿足要求時視窗的狀態: 這裡是包含字串t的所有元素就可以,不要求有序,那麼使用雜湊表來記錄就是很好的辦法,同時要求最短,即後續要最佳化,因為可能T的元素會在s中常重複出現,那麼雜湊表的值設定為頻率就能很好達到——》元素出現,並且頻率一次就是最短的狀態。因為是字元,所以雜湊表設計為 var targetFreq :=map[byte]int。 那麼targetFreq的長度就代表了目標字串的元素種類。

點選檢視程式碼
func minWindow(s string, t string) string {
   if len(s)==0 || len(t)==0{return ""}

   left,right,matchCount:=0,0,0
   //記錄最短序列的開始位置,結合最短長度即可得到最短序列
   start:=0
   //記錄最短長度
   minLength := len(s)+1
   //記錄目標序列的元素的種類和個數。這樣無論元素是否有重複,只要這兩個要求都滿足就可以
   targetFreq := make(map[byte]int)
    for i := 0; i < len(t); i++ {
        targetFreq[t[i]]++
    }

    //用於記錄當前視窗中的元素種類數量情況
    windowFreq := make(map[byte]int)

    for right<len(s){
        charRight := s[right]
        right++
        //只統計目標序列中的元素即可。
        if _,exists:=targetFreq[charRight];exists{
            windowFreq[charRight]++
            //如果某個元素的數量已經滿足了目標序列的數量要求,那麼完成的元素數量++
            if windowFreq[charRight] == targetFreq[charRight] {
                matchCount++
            }
        }
        //所有元素數量已經符合要求,現在看能否縮小序列
        for matchCount == len(targetFreq){
            if right-left <minLength{
                minLength = right-left
                start = left
            }
             charLeft:= s[left]
             left++
            //    嘗試縮小邊界
             if _,exists:=targetFreq[charLeft];exists{
                 if windowFreq[charLeft] == targetFreq[charLeft]{
                     matchCount--
                 }
                 windowFreq[charLeft]--
             }
        }
    }
    if minLength == len(s)+1{return ""}
    return s[start:start+minLength]
}

相關文章