leetcode解題-滑動窗口

滑動窗口思路:
解決部分數組問題時,設置兩個索引下標i,j{i,j}i{i}爲左邊界,j{j}爲右邊界,逐漸遍歷整個數組,i{i}j{j}組成的子數組形成長度變化的滑動窗口,直至i{i}遍歷完整個數組。

應用一:

Leetcode 3:Longest Substring Without Repeating Characters
在一個字符串中尋找沒有重複字母的最長子串,返回長度值。
解法1:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 滑動窗口
        result = {}
        left = 0
        ans = 0
        
        for i, c in enumerate(s):
            # 把所有的字符存放在字典裏,每次對一個字符進行檢查:
            # if c在result裏,且result[c]的索引>= left【說明字符重複了】
            #     更新left爲索引值+1
            # else 最大子串長度=i-left+1或者當前的最大值
            # 更新/添加新字符的索引。【始終保持當前value是某字符索引的最大值】
            
            if c in result and result[c]>=left:
                left = result[c]+1
            else:
                ans = max(i-left+1, ans)
            result[c]=i
        return ans

解法2:

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

應用二:

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章