力扣-python-滑动窗口合集

文章目录

  • 滑动窗口长度固定
    • 28.实现strStr()
    • 567.字符串的排列
  • 滑动窗口长度不固定
    • 209.长度最小的子数组
    • 3.无重复字符的最长子串
    • 485. 最大连续1的个数
    • 487. 最大连续1的个数2
    • 1004.最大连续1的个数3

滑动窗口长度固定

滑动窗口模板:

min_len = float('inf')
max_len = float('-inf')
start = 0
for end in range(len(滑动窗口)-1, len(字符串/列表)):
	while() or if()
if max_len == float('-inf')(or if min_len == float('inf')):
	return 0
elsereturn max_len(or return min_len)

28.实现strStr()

题目:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1

  • 窗口长度固定,为len(needle)
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
    	start = 0
    	for end in range(len(needle)-1, len(haystack)):
    		if haystack[start:end-start+1] == needle:
    			return start
    		start += 1
 		return -1

567.字符串的排列

题目:给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列(不考虑次序)。如果是,返回 true ;否则,返回 false 。

  • 只求s2中是否含有s1的排列,即不考虑次序,‘ab’==‘ba’。采用字典很合适
  • 窗口长度固定,为len(s1)
class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
    	start = 0
    	from collections import Counter
    	adict = Counter(s1)
    	for end in range(len(s1)-1, len(s2)):
    		if Counter(s2[start:end+1]) == adict:
    			return True
    		else:
    			start += 1
    	return False	

滑动窗口长度不固定

209.长度最小的子数组

题目:给定一个数组nums、一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0 。

  • 窗口长度不固定
  • 最小,min_len上场
  • 和>target 且连续子数组,假设数组为[1,2,2,3,3],target=7。那么在变动start,end不变的前提下,子数组[1,2,2,3]和子数组[2,2,3]是满足条件的。因此需要用while循环来判断start到end中的每个子数组是否满足和>target 这个条件。
class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
    min_len = float('inf')
    start = 0
    cur_sum = 0 // 记录以start开头,end为末尾的子数组的和
    for end in range(len(nums)):
    	cur_sum += nums[end]
    	while start <= end and cur_sum >= target:  // 子数组循环里需要做的事情
    		min_len = min(min_len, end-start+1) // 当条件满足时,更新min_len的长度
    		cur_sum -= nums[start]  // 看看数组里是否还有其他的子数组符合循环条件
    		start += 1  // 更新start的值,方便重新更新min_len
    if min_len == float('inf'):
    	return 0
    else:
    	return min_len

3.无重复字符的最长子串

题目:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。 s = abcabcbb

  • 窗口长度不固定
  • 最长,max_len上场
  • 循环条件是无重复字符(当起始位置为start,第一个无重复子串的结束位置为end,那么【start+1:end】等子串肯定是无重复,我们只需要依次增大end来获取开头在【start:end】间的所有无重复子串)
  • 什么时候移动start,对于字符串abca,当出现重复字符a时,我们需要移动start来判断bc中是否含有字符a
  • 什么时候更新max_len,// while循环出来后可以保证列表中无重复的字符,此时可以更新max_len
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
    	max_len = float('-inf')
    	start = 0
    	l = []
    	for end in range(len(s)):
    		while s[end] in l:
    			s.remove(s[start])
    			start += 1
    		max_len = max(max_len, end - start + 1)  
    		l.append(s[end])
    	if max_len == float('-inf'):
    		return 0
    	else:
    		return max_len		

485. 最大连续1的个数

题目:给定一个二进制数组 nums , 计算其中最大连续 1 的个数。

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        start = 0
        count = 0
        max_len = float('-inf')
        for end in range(len(nums)):
            if nums[end] == 1:
                count += 1
            while count < end - start + 1:
                if nums[start] == 1:
                    count -= 1
                start += 1
            max_len = max(max_len, end - start + 1)
        if max_len == float('-inf'):
            return 0
        else:
            return max_len

487. 最大连续1的个数2

题目:给定一个二进制数组,你可以最多将 1 个 0 翻转为 1,找出其中最大连续 1 的个数。

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        start = 0
        count = 0
        max_len = float('-inf')
        for end in range(len(nums)):
            if nums[end] == 1:
                count += 1
            while count + 1 < end - start + 1:
                if nums[start] == 1:
                    count -= 1
                start += 1
            max_len = max(max_len, end - start + 1)
        if max_len == float('-inf'):
            return 0
        else:
            return max_len

1004.最大连续1的个数3

题目:给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回数组中连续 1 的最大个数 。

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        start = 0
        count = 0
        max_len = float('-inf')
        for end in range(len(nums)):
            if nums[end] == 1:
                count += 1
            while count + k < end - start + 1:
                if nums[start] == 1:
                    count -= 1
                start += 1
            max_len = max(max_len, end - start + 1)
       
        if max_len == float('-inf'):
            return 0
        else:
            return max_len

485,487,1004都可以套用滑动窗口的同一个模板。
如果窗口的长度比count+k的极限长度还要大,说明这个窗口长度是有问题的,就要想办法更新一些窗口的附属值。窗口满足要求就可以计算长度了。

你可能感兴趣的:(python学习,leetcode,python,算法)