0x3f 第20天 三更24-32 hot100子串

1.滑动窗口最大值

首先我们来回顾一下一个新的数据结构的理解: 单调队列

单调队列普遍是双端队列,且队列里的元素是单调递减的,这样就引申出了他的核心目的:

动态维护候选元素的最大值

  • 单调队列的作用是在窗口滑动时,始终让队列头部是当前窗口的最大值下标
  • 为什么存的是下标呢,后来慢慢发现存下标能得到更多的信息,比如维护窗口长度
  • 队尾是 "清理一窝":新元素来了,所有比它小的旧候选都没用了,得全清;
  • 队首是 "清理一个":窗口挪一步,最多只漏出去一个队首元素,清一个就够。
  • 因此入队用的是while,出队用的是if

用单调递减的结构:保证队首始终是当前窗口的最大值

每个元素只入队出队一次,相比暴力解法不断的滑动窗口,把 "求窗口最大值" 的时间从 O (k) 降到 O (1)

回到本题:

核心思路: 1.发现使用定长的单调队列完美解决这个需求

入队:枚举所有元素、如果新进元素比队列最后一个大,直接踢掉

出队:由于定长,超出长度时,踢掉老大

存储结果:当队列长度为3,就可以存储老大的值

每个元素只入队出队一次 时间复杂度O(n)

单调队列的空间开销由「窗口大小 k」决定,而非数组长度 n空间复杂度O(k)

复制代码
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        ans = []
        q = deque()
        for i,x in enumerate(nums):
            1.入队
            while q and x>=nums[q[-1]]:
                q.pop()
            q.append(i)
            2.出队
            if i-q[0]+1>k:
                q.popleft()
            3.记录答案
            if i+1>=k:
                ans.append(nums[q[0]])
        return ans

2.最小覆盖子串

首先引入一个新的cnt的功能

比如目前有cnt_s=Counter(s) cnt_t=Counter(t)

cnt_s >= cnt_t:覆盖 简单说就是 cnt_s 包含 cnt_t 所有字符的频次要求

cnt_s={A:2 B:2 C:3····} cnt_t = {A:1 B:1 C:1}

可以直接比较

本题核心 1.变量 ans_left ans_right保存当前最好的结果

left right不断再更新窗口长度

if right - left < ans_right - ans_left:说明有更优解,更新

2.其他都是普通滑动窗口的模板

3.边界条件ans_left:初始就是-1,不存在的边界

只有当找到真正的有效覆盖子串 时,才会更新 ans_leftans_right 为合法的下标

复制代码
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        m = len(s)
        n = len(t)
        ans_left = -1
        ans_right = m
        cnt_s = Counter()
        cnt_t = Counter(t)

        left = 0
        for right,right_str in enumerate(s):
            cnt_s[right_str]+=1
            while cnt_s>=cnt_t:
                if right-left<ans_right-ans_left:
                    ans_left,ans_right=left,right
                cnt_s[s[left]]-=1
                left+=1
        if ans_left==-1:
            return ''
        else:
            return s[ans_left:ans_right+1]
相关推荐
清酒难咽15 小时前
算法案例之递归
c++·经验分享·算法
Rabbit_QL15 小时前
【水印添加工具】从零设计一个工程级 Python 图片水印工具:WaterMask 架构与实现
开发语言·python
张柏慈15 小时前
Java性能优化:实战技巧与案例解析
java
天“码”行空15 小时前
简化Lambda——方法引用
java·开发语言
让我上个超影吧15 小时前
【力扣26&80】删除有序数组中的重复项
算法·leetcode
带刺的坐椅16 小时前
MCP 进化:让静态 Tool 进化为具备“上下文感知”的远程 Skills
java·ai·llm·agent·solon·mcp·tool-call·skills
java1234_小锋16 小时前
Java线程之间是如何通信的?
java·开发语言
张张努力变强16 小时前
C++ Date日期类的设计与实现全解析
java·开发语言·c++·算法
沉默-_-17 小时前
力扣hot100滑动窗口(C++)
数据结构·c++·学习·算法·滑动窗口
钱彬 (Qian Bin)17 小时前
项目实践19—全球证件智能识别系统(优化检索算法:从MobileNet转EfficientNet)
算法·全球证件识别