【算法——Python实现】滑动窗口解决数组问题

滑动窗口思路:
解决部分数组问题时,设置两个索引下标i,j,i为左边界,j为右边界,逐渐遍历整个数组,i和j组成的子数组形成长度变化的滑动窗口,直至i遍历完整个数组。

应用一:
Leetcode 209:Minimum Size Subarray Sum
给定一个整型数组和一个数字s,找到数组中最短的一个连续子数组,使得连续子数组的数字和sum>=s,返回这个最短的连续子数组的长度值

class Solution(object):
    def minSubArrayLen(self, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        """
        # 滑动窗口,右边界右移,找到一个连续子数组和大于s,记录长度,然后将左边界右移,当和小于s时,再右移右边界,直到找到新的连续子数组
        # 时间复杂度O(n),空间复杂度O(1)
        l = 0
        r = -1  # nums[l...r]为滑动窗口
        sums = 0
        res = len(nums) + 1 # 初始设为不可能取到的最大值
        while l < len(nums):
            if sums < s and r < len(nums) - 1:
                r += 1
                sums += nums[r]
            else:
                sums -= nums[l]
                l += 1
            if sums >= s:
                res = min(res, r-l+1)
        if res == len(nums) + 1:
            return 0
        return res

应用二:
Leetcode 3:Longest Substring Without Repeating Characters
在一个字符串中寻找没有重复字母的最长子串,返回长度值

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        # 滑动窗口,右边界右移,直到找到有重复字符,记录长度,然后将左边界右移到重复的数组+1位置,再继续右移右边界,直到找到新的重复字符
        # 时间复杂度O(n),空间复杂度O(1)
        freq = [0 for _ in range(256)]  # 用于记录每个字符串当前出现频率,索引为每个字符串对应的ASCII码
        l = 0
        r = -1  # nums[l...r]为滑动窗口
        res = 0  # 初始化为最小
        while l < len(s):
            # 当右边界下一个位置s[r+1]的频率为0时才右移,否则有重复字符,就右移左边界直到没有重复字符
            if r < len(s)-1 == 0 and freq[ord(s[r+1])] == 0:
                r += 1
                freq[ord(s[r])] += 1
            else:
                freq[ord(s[l])] -= 1
                l += 1
            # 每次循环中滑动窗口内永远不会有重复字符,所以每次都可以做比较,最终res为最大值
            res = max(res, r-l+1)
        return res

你可能感兴趣的:(算法——Python实现)