📜  python滑动窗口 - Python(1)

📅  最后修改于: 2023-12-03 15:34:31.089000             🧑  作者: Mango

python滑动窗口 - Python

Python滑动窗口是一种常见的算法技巧,用于解决一些字符串、数组、列表等问题。滑动窗口可以通过移动窗口的起始位置和结束位置来解决问题,通常时间复杂度为O(N)。

概述

滑动窗口的基本思想是维护一个包含当前解的滑动窗口,通过移动窗口的起始位置和结束位置来更新滑动窗口,并据此计算解。通常使用两个指针 startend 来表示滑动窗口的起始位置和结束位置。

通常使用while循环实现滑动窗口,while循环的终止条件一般是窗口结束位置end越界或者找到了符合题目要求的解。

代码示例:

def sliding_window(s: str) -> List:
    n = len(s)
    # 定义起始位置和结束位置
    start, end = 0, 0
    res = []
    while end < n:
        # 判断是否符合题目要求
        if s[end] not in s[start:end]:
            end += 1
        else:
            # 更新答案
            res.append(s[start:end])
            start += 1
    return res
实战
1. 最小覆盖子串

给定两个字符串 s 和 t,返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""。

示例:

输入: s = "ADOBECODEBANC", t = "ABC" 输出: "BANC"

代码示例:

def min_window(s: str, t: str) -> str:
    if not s or not t:
        return ""
    # 定义哈希表和计数器
    dic = {}
    count = len(t)
    for i in t:
        dic[i] = dic.get(i, 0) + 1
    # 定义起始位置和结束位置
    start, end = 0, 0
    minlen = float('inf')
    minstr = ""
    while end < len(s):
        # 判断字符串是否在字典中
        if s[end] in dic:
            if dic[s[end]] > 0:
                count -= 1
            dic[s[end]] -= 1
        end += 1
        # 判断是否符合题目要求
        while count == 0:
            if end - start < minlen:
                minlen = end - start
                minstr = s[start:end]
            if s[start] in dic:
                dic[s[start]] += 1
                if dic[s[start]] > 0:
                    count += 1
            start += 1
    return minstr
2. 无重复字符的最长子串

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

示例:

输入: s = "abcabcbb" 输出: 3

代码示例:

def length_of_longest_substring(s: str) -> int:
    if not s:
        return 0
    dic = {}
    res = 0
    start, end = 0, 0
    while end < len(s):
        # 判断是否出现重复字符
        if s[end] not in dic:
            dic[s[end]] = 1
        else:
            dic[s[end]] += 1
        end += 1
        # 判断是否符合题目要求
        while dic[s[end-1]] > 1:
            dic[s[start]] -= 1
            start += 1
        res = max(res, end-start)
    return res
3. 滑动窗口的最大值

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 输出: [3,3,5,5,6,7]

代码示例:

from collections import deque

def max_sliding_window(nums: List[int], k: int) -> List[int]:
    queue = deque()
    res = []
    for i in range(len(nums)):
        # 判断是否滑出窗口范围,是则弹出队首元素
        if i >= k and queue[0] <= i - k:
            queue.popleft()
        # 保持队列单调递减
        while queue and nums[i] >= nums[queue[-1]]:
            queue.pop()
        queue.append(i)
        # 队首元素即为最大值
        if i >= k - 1:
            res.append(nums[queue[0]])
    return res
总结

滑动窗口是一种常见的算法技巧,时间复杂度通常为O(N)。在遇到一些字符串、数组、列表等问题时,可以考虑使用滑动窗口解决。通过维护滑动窗口的起始位置和结束位置,可以在O(N)时间内得到解,实现简单易懂。