1. 程式人生 > >【演算法——Python實現】滑動視窗解決陣列問題

【演算法——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