1. 程式人生 > 實用技巧 >leetcode刷題筆記七十六題 最小覆蓋子串

leetcode刷題筆記七十六題 最小覆蓋子串

leetcode刷題筆記七十六題 最小覆蓋子串

源地址:76. 最小覆蓋子串

問題描述:

給你一個字串 S、一個字串 T,請在字串 S 裡面找出:包含 T 所有字元的最小子串。

示例:

輸入: S = "ADOBECODEBANC", T = "ABC"
輸出: "BANC"
說明:

如果 S 中不存這樣的子串,則返回空字串 ""。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。

/**
本題為典型的滑動視窗問題
此類問題的基本模板是:
while(right < rightEdge){
	將right內容加入滑動視窗
	right++
	windowLen++
	
	while(視窗內內容滿足要求){
		更新視窗start位置與長度
		將視窗左側元素移除視窗
		left--
	}
}
*/
import scala.collection.mutable
object Solution {
    def minWindow(s: String, t: String): String = {
        if (s.length < t.length) return ""
        
        /**
        needs: 需求對映,本題中為t的組成對映
        windows: 視窗內對映
        left: 視窗左端
        right: 視窗右端
        vaild: 視窗滿足條件
        start: 滿足條件開始位置
        len: 滿足條件的長度
        */
        val needs = mutable.Map[Char, Int]()
        val windows = mutable.Map[Char, Int]()
        var left = 0
        var right = 0
        var vaild = 0
        var start = 0
        var len = Int.MaxValue

        t.foreach(c => needs(c) = needs.getOrElse(c, 0) + 1)

        while(right < s.length){ 
            val tempChar = s(right)
            right += 1
            //當右側元素出現在needs中時,將其加入windows
            //如果此時windows中關於tempChar滿足needs要求,vaild更新
            if(needs.contains(tempChar)){
                windows(tempChar) = windows.getOrElse(tempChar, 0) + 1
                if(windows(tempChar) == needs(tempChar)) vaild += 1
            }
            
            //vaild只有windows全部滿足needs要求的情況下,才能和needs.size相等
            while(vaild == needs.size){
                //更新start len
                if(right - left < len){
                    start = left
                    len = right - left
                }
                val backChar = s(left)
                left += 1
                //取出左側元素,需要注意的是,左側元素移除條件為windows中移除該元素後仍滿足要求,以本題為例防止出現ABCCB的情況
                if(needs.contains(backChar)){
                    if(windows(backChar) >= needs(backChar)){
                        windows(backChar) -= 1
                        //去除後不滿足要求 更新vaild 退出左移
                        if(windows(backChar) < needs(backChar)) vaild -= 1 
                    }
                }
            }
        }
        if(len == Int.MaxValue) return ""
        else return s.substring(start, start+len)
    }
}