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)
    }
}

相关文章

这篇文章主要介绍LeetCode二维数组中如何实现对角线遍历,文...
这篇文章主要介绍了leetcode如何解决从根到叶的二进制数之和...
这篇文章主要为大家展示了“leetcode多线程之如何解决按序打...
这篇文章给大家分享的是有关LeetCode中二维数组如何实现旋转...
这篇文章主要介绍了LeetCode中二维数组如何实现零矩阵,具有...
本篇内容介绍了“leetcode怎么解决青蛙跳台阶问题”的有关知...