滑动窗口算法 - LCR 014. 字符串的排列

前言

接前文 滑动窗口算法 - LC76 最小覆盖子串-CSDN博客,此题也是套用滑窗模板,但是在两个细节点处稍有不同。

正文

LCR 014. 字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。

换句话说,第一个字符串的排列之一是第二个字符串的 子串 。

题解:

func checkInclusion(s2 string, s1 string) bool {
	window := make(map[byte]int)
	need := make(map[byte]int)
	for i := 0; i < len(s2); i++ {
		need[s2[i]]++
	}
	n := len(s1)
	l, r := 0, 0
	valid := 0
	for r < n {
		c := s1[r]
		r++
		if need[c] > 0 {
			window[c]++
			if need[c] == window[c] {
				valid++
			}
		}

		for r-l == len(s2) {
			if valid == len(need) {
				return true
			}
			d := s1[l]
			l++
			if need[d] > 0 {
				if need[d] == window[d] {
					valid--
				}
				window[d]--
			}
		}
	}
	return false
}

细节点:

(1)注意窗口收缩的条件发生改变,即左指针移动的条件发生改变,只要当前窗口的长度>=目标字符串的长度,即l-r >len(s2),注意不是l-r > len(need)那么就开始收缩,因为我们要找的覆盖子串是要和目标字符串长度相等的不同排列

(2)len(need)是目标字符串里不重复元素个数,len(s2)是目标字符串长度,当r-l == len(s2)并且valid==len(need)时,说明在s1中找到了s2的不同排列的字符串,所以可以直接return true。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值