【经典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


相关文章
|
8月前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
10月前
|
机器学习/深度学习 Dragonfly 人工智能
基于蜻蜓算法优化支持向量机(DA-SVM)的数据多特征分类预测研究(Matlab代码实现)
基于蜻蜓算法优化支持向量机(DA-SVM)的数据多特征分类预测研究(Matlab代码实现)
214 1
|
9月前
|
机器学习/深度学习 算法 调度
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
640 0
|
8月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
8月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
10月前
|
机器学习/深度学习 传感器 数据采集
【23年新算法】基于鱼鹰算法OOA-Transformer-BiLSTM多特征分类预测附Matlab代码 (多输入单输出)(Matlab代码实现)
【23年新算法】基于鱼鹰算法OOA-Transformer-BiLSTM多特征分类预测附Matlab代码 (多输入单输出)(Matlab代码实现)
551 0
|
11月前
|
机器学习/深度学习 人工智能 算法
AP聚类算法实现三维数据点分类
AP聚类算法实现三维数据点分类
373 0
|
机器学习/深度学习 算法 数据可视化
利用SVM(支持向量机)分类算法对鸢尾花数据集进行分类
本文介绍了如何使用支持向量机(SVM)算法对鸢尾花数据集进行分类。作者通过Python的sklearn库加载数据,并利用pandas、matplotlib等工具进行数据分析和可视化。
1365 70
|
机器学习/深度学习 资源调度 算法
基于入侵野草算法的KNN分类优化matlab仿真
本程序基于入侵野草算法(IWO)优化KNN分类器,通过模拟自然界中野草的扩散与竞争过程,寻找最优特征组合和超参数。核心步骤包括初始化、繁殖、变异和选择,以提升KNN分类效果。程序在MATLAB2022A上运行,展示了优化后的分类性能。该方法适用于高维数据和复杂分类任务,显著提高了分类准确性。
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
451 4

热门文章

最新文章