当前位置: 首页 > article >正文

力扣 -- 滑动窗口

定长的窗口

239. 滑动窗口最大值

239. 滑动窗口最大值
给定一定长度为 k k k 的窗口,从数组的最左侧移动到到数组最右侧,每次移动一位,移动过程中纪录窗口中最大值。

难点:移动的过程中,如何纪录窗口内的最大值。
我们可以使用双端队列 / 单调队列创建一个窗口,其里面的元素是索引而不是数组的元素;在移动的过程中我们不断维护队列的单调性,即队列中下标对应的数组元素是单调递增的。此外,若要保持窗口的大小为 k k k 的话,则当前下标 i i i 与队头数值 j j j 需要不等式 i − j < k i-j < k ij<k 成立。
若上述的条件满足,则队列中的数值对应的数组元素就是当前窗口的最大值。

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        n, ans = len(nums), []
        deque = collections.deque()
        for j in range(n):
            while len(deque) != 0 and nums[j] >= nums[deque[-1]]:
                deque.pop() # 如果新来的元素大于队尾元素,则删除队尾元素
            deque.append(j)
            if j - deque[0] >= k:  # 非窗口内的元素
                deque.popleft()
            if j >= k - 1: 
                ans.append(nums[deque[0]])
        return ans

不定长的窗口

862. 和至少为 K 的最短子数组

862. 和至少为 K 的最短子数组
给定一个整数数组 nums 和一个整数 k k k,需要找到和至少为 k k k 的最短子数组的长度。如果没有这样的子数组,则返回 -1。

难点:数组的范围为 [ − 1 0 5 , 1 0 5 ] [-10^5, 10^5] [105,105],即数组可能包含负数,不能简单地移动左指针来收缩窗口,否则会错过满足条件的较短子数组,因此双指针的窗口不适用。

在这种情况下,我们可以使用单调队列和前缀和数组,它能动态地保持一个符合条件的窗口并确保子数组长度尽可能短。

  • 为了快速求得子数组的和,我们使用前缀和数组 s s s 来求得数组的 [ i : j ] [i: j] [i:j] 这个区域内的和,即 sum ( n u m s [ i : j ] ) = s [ j ] − s [ i ] \text{sum}(nums[i:j]) = \text{s}[j] - \text{s}[i] sum(nums[i:j])=s[j]s[i]。此时若这个 sum ( n u m s [ i : j ] ) = s [ j ] − s [ i ] ≥ k \text{sum}(nums[i:j]) = s[j] - s[i] \geq k sum(nums[i:j])=s[j]s[i]k,则表示区间 [ i : j ] [i: j] [i:j] 是一个满足条件的子数组。
  • 为了找到最短子数组的长度,我们使用一个双端队列 deque 存储前缀和数组的索引,维护 deque 单调递增,即队列中的索引对应的前缀和元素在队列中是单调递增的。
    队头条件的检查:当遍历到索引 j j j 时, 检查队头索引 i i i 是否存在满足 s [ j ] − s [ i ] > = k s[j] - s[i] >= k s[j]s[i]>=k,若满足则更新答案,并将队头索引出队。额外的,我们还要继续检查 [ i + 1 : j ] [i+1: j] [i+1:j] 是否满足以上的条件(得到更短的长度)。
    保持单调性:遍历到索引 j j j 时,移除队尾所有满足 s [ j ] ≤ s [ q [ − 1 ] ] s[j] \leq s[q[-1]] s[j]s[q[1]] 的索引。因为存在队尾元素 i i i,当 s [ i ] ≥ s [ j ] s[i] \geq s[j] s[i]s[j] 时, s [ i ] s[i] s[i] 不再有用,因为 s [ j ] s[j] s[j] 更小且出现在更右侧,未来更有可能形成更短的子数组(存在未来的元素 x x x x ≥ s [ i ] x \geq s[i] xs[i],若 x − s [ i ] ≥ k x-s[i] \geq k xs[i]k,则 x − [ j ] ≥ k x-[j] \geq k x[j]k 成立,则从 j j j 开始的范围更小)。
class Solution:
    def shortestSubarray(self, nums: List[int], k: int) -> int:
        s = list(accumulate(nums, initial=0))  # 前缀和数组,从 0 开始
        ans, q = inf, deque()
        for i, curS in enumerate(s):
            while q and curS-s[q[0]] >= k:
                ans = min(ans, i-q.popleft())
            while q and s[q[-1]] >= curS:
                q.pop()
            q.append(i)
        return ans if ans < inf else -1

http://www.kler.cn/a/384772.html

相关文章:

  • 【C】无类型指针及函数指针
  • 17、论文阅读:VMamba:视觉状态空间模型
  • HCIP--3实验- 链路聚合,VLAN间通讯,Super VLAN,MSTP,VRRPip配置,静态路由,环回,缺省,空接口,NAT
  • windows C#-异常和异常处理概述
  • HTML前端页面设计静态网站-仿百度
  • Docker + Jenkins + gitee 实现CICD环境搭建
  • Pytorch训练时报nan
  • laravel chunkById 分块查询 使用时的问题
  • Spring Cloud Bus快速入门Demo
  • 第九周预习报告
  • qt QItemSelectionModel详解
  • 多个服务器共享同一个Redis Cluster集群,并且可以使用Redisson分布式锁
  • Git LFS
  • 专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。
  • 内置函数【MySQL】
  • 生产环境中使用:带有核函数的 SVM 处理非线性问题
  • Unity 的 WebGL 构建中资源图片访问方式
  • 人工智能:重塑生活与工作的神奇力量
  • WebRTC REMB算法
  • AIGC--如何在内容创作中合理使用AI生成工具?
  • H.265流媒体播放器EasyPlayer.js网页web无插件播放器:如何优化加载速度
  • 使用 Java 实现邮件发送功能
  • Matlab实现鲸鱼优化算法优化随机森林算法模型 (WOA-RF)(附源码)
  • 23isctf
  • tomcat 开启远程debug模式
  • vue组件获取props中的数据并绑定到form表单 el-form-item的v-model中方法