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]
相关推荐
zfoo-framework1 小时前
[修改代码使用]codex官方app中使用中转(不需要cc-switch) 1.config.toml 2.sk方式登录
java
天佑木枫1 小时前
15天Python入门系列 · 序
开发语言·python
happylifetree1 小时前
Python017-第二章15.数据容器-dict常用操作
python
装不满的克莱因瓶1 小时前
了解 LangChain 中的 LLM 与 ChatModel 的差异
人工智能·python·ai·langchain·llm·agent·chatmodel
逍遥德1 小时前
MQTT教程详解-05.SpringBoot集成mqtt client 性能分析
java·spring boot·spring·mt
云烟成雨TD2 小时前
Spring AI 1.x 系列【54】Retry 机制分析
java·人工智能·spring
weixin_523185322 小时前
Collections.unmodifiableMap详解:真的不可修改吗?
java·linux·前端
手写码匠2 小时前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
点燃大海2 小时前
SpringAI构建智能体
java·spring boot·spring·springai智能体
xier_ran2 小时前
【infra之路】02_RadixAttention与KV_Cache管理
java·spring boot·spring