LC76 - 最小覆盖子串

LeetCode - 76.最小覆盖子串

题目

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"

示例 2:

输入:s = "a", t = "a"
输出:"a"

示例 3:

输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

思路

继上一篇 LC904 - 水果成篮, 这道题的解法也是滑动窗口。
我们需要统计 t 中字符的种类和个数,这是为了方便判断 t 是否被包含在 s 的子串中。

代码

func minWindow(s string, t string) string {
    
    
	result := ""
	resultLen := math.MaxInt32
	sHashmap := map[uint8]int{
    
    }
	tHashmap := map[uint8]int{
    
    }
	// 统计 t 字符串中的 字符及个数
	for i := 0; i < len(t); i ++ {
    
    
		tHashmap[t[i]] ++
	}

	left, right, length := 0, 0, len(s)
	
	for ; right < length; right ++ {
    
    
		// 每向右滑动一格
		sHashmap[s[right]] ++
		// 判断当前窗口是否满足条件
		for ;left <= right && check(sHashmap, tHashmap); {
    
    
			// 满足条件了,更新一下结果
			if resultLen > right - left + 1 {
    
    
				resultLen = right - left + 1
				result = s[left : right + 1]
			}
			// 结果更新后,便可以缩小滑动窗口大小,即 left++
			sHashmap[s[left]] --
			// 如果字符为0了删除
			if sHashmap[s[left]] == 0 {
    
    
				delete(sHashmap, s[left])
			}
			left ++
		}
	}

	return result
}

func check(sHashmap, tHashmap map[uint8]int) bool {
    
    
	for item := range tHashmap {
    
    
		sNum, ok := sHashmap[item]
		if !ok || sNum < tHashmap[item] {
    
    
			return false
		}
	}
	return true
}

猜你喜欢

转载自blog.csdn.net/qq_44336650/article/details/120887573