leetcode刷題筆記七十六題 最小覆蓋子串
阿新 • • 發佈:2020-07-22
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) } }