【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串

简介: 【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串

一般应用场景

数组,字符串子串等问题。

通用模板

双指针大致逻辑如下:

left = 0
right  = 0
while  right < len(s):
    # 右指针右移增大窗口
    window.add(s[right])
    right  += 1
    while isvalid:
        # 当满足某种条件时开始从左边收缩窗口
        window.remove(s[left])
        left += 1

代码模板:

def slidingWindow(s, t):
    from collections import defaultdict
    # defaultdict(int)对于不存在的键默认值为0,
    # 可以直接进行window[c] += 1的操作,免去了判断过程
    window = defaultdict(int)
    needs  = defaultdict(int)
    left = 0
    right = 0
    for c in t:
        needs[c] += 1
    while right < len(s):
        # c1为移入窗口的字符
        c1 = s[right]
        # 窗口右移
        right += 1
        # 进行窗口内数据的相关操作
        # TODO
        # 判断左侧窗口是否要收缩
        while window needs shrink:
            # c2为将要移出窗口的字符
            c2 = s[left]
            # 左指针右移,收缩窗口
            left += 1
            # 进行窗口内数据的相关操作
            # TODO

相关Leetcode题目

  1. 最小覆盖子串

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        from collections import defaultdict
        needs = defaultdict(int)
        window = defaultdict(int)
        left = 0
        right = 0
        count = 0 #window中满足条件的字符数
        start = 0 #记录最小子串的起始位置
        min_len = float('inf') #记录最小子串的长度
        for c in t:
            needs[c] += 1
        while right < len(s):
            c1 = s[right]
            right += 1
            if  c1 in needs:
                window[c1] += 1
                if window[c1] == needs[c1]:
                    count += 1
            while count == len(needs):
                # 更新最小覆盖子串
                if right - left < min_len:
                    start = left
                    min_len = right - left
                c2 = s[left]
                left += 1
                if c2 in needs:
                    window[c2] -= 1
                    if window[c2] < needs[c2]:
                        count -= 1
        if min_len == float('inf'):
            return ''
        else:
            return s[start:start+min_len]
  1. 字符串排列

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        from collections  import defaultdict
        needs = defaultdict(int)
        for c in s1:
            needs[c] += 1
        window = defaultdict(int)
        left = 0
        right = 0
        count = 0
        while right < len(s2):
            c1 = s2[right]
            right += 1
            if c1 in needs:
                window[c1] += 1
                if window[c1] == needs[c1]:
                    count += 1
            while count == len(needs):
                if right - left == len(s1):
                    # 如果子串长度与s1相等则包含
                    return True
                c2 = s2[left]
                if c2 in needs:
                    window[c2] -= 1
                    if window[c2] < needs[c2]:
                        count -= 1
                left += 1
        return False
  1. 找所有字母异位词

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        from collections import defaultdict
        needs = defaultdict(int)
        window = defaultdict(int)
        left = 0
        right = 0
        count = 0
        res = []
        for c in p:
            needs[c] += 1
        while right < len(s):
            c1 = s[right]
            if c1 in needs:
                window[c1] += 1
                if window[c1] == needs[c1]:
                    count += 1
            right += 1
            while count == len(needs):
                if right - left == len(p):
                    res.append(left)
                c2 = s[left]
                if c2 in needs:
                    window[c2] -= 1
                    if window[c2] < needs[c2]:
                        count -= 1
                left += 1
        return res
  1. 最长无重复子串

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        max_len = 0
        left = 0
        right = 0
        n = len(s)
        from collections import defaultdict
        window = defaultdict(int)
        while right < n:
            c1 = s[right]
            right += 1
            window[c1] += 1
            while window[c1] > 1:
                c2 = s[left]
                left += 1
                window[c2] -= 1
            max_len = max(max_len, right - left)
        return max_len


相关文章
|
2月前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
2月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
8月前
|
机器学习/深度学习 监控 算法
员工上网行为监控软件中基于滑动窗口的C#流量统计算法解析​
在数字化办公环境中,员工上网行为监控软件需要高效处理海量网络请求数据,同时实时识别异常行为(如高频访问非工作网站)。传统的时间序列统计方法因计算复杂度过高,难以满足低延迟需求。本文将介绍一种基于滑动窗口的C#统计算法,通过动态时间窗口管理,实现高效的行为模式分析与流量计数。
227 2
|
6月前
|
存储 机器学习/深度学习 监控
公司电脑上网监控中滑动窗口算法的理论构建与工程实现
本文提出一种基于滑动窗口算法的实时网络流量监控框架,旨在强化企业信息安全防护体系。系统采用分层架构设计,包含数据采集、处理与分析决策三大模块,通过 Java 实现核心功能。利用滑动窗口技术动态分析流量模式,结合阈值检测与机器学习模型识别异常行为。实验表明,该方案在保证高检测准确率的同时支持大规模并发处理,为企业数字化转型提供可靠保障。
153 0
|
8月前
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
207 3
|
9月前
|
存储 监控 算法
基于 PHP 语言的滑动窗口频率统计算法在公司局域网监控电脑日志分析中的应用研究
在当代企业网络架构中,公司局域网监控电脑系统需实时处理海量终端设备产生的连接日志。每台设备平均每分钟生成 3 至 5 条网络请求记录,这对监控系统的数据处理能力提出了极高要求。传统关系型数据库在应对这种高频写入场景时,性能往往难以令人满意。故而,引入特定的内存数据结构与优化算法成为必然选择。
240 3
|
12月前
|
算法
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
303 1
两个字符串匹配出最长公共子序列算法
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
260 1
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
259 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行

热门文章

最新文章