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

LeetCode100-239滑动窗口最大值

本文基于各个大佬的文章

上点关注下点赞,明天一定更灿烂!


前言

        Python基础好像会了又好像没会,所有我直接开始刷leetcode一边抄样例代码一边学习吧。本系列文章用来记录学习中的思考,写给自己看的,也欢迎大家在评论区指导~

        您的每一条评论都会让我更有学习的动力。


一、分析题目

一不留神又断更两天了,坚持一件事情真的好难,对我这种三分钟热度的人来说。这几天沉迷绣绣娘和金铲铲无法自拔,罪过啊。今天连着更四道题!

二、思路以及代码

思路:用一个空列表来存储最后每个窗口最大值,每个窗口内比较大小,记录最大值

from typing import List
def maxSlidingWindow(nums: List[int], k: int) -> List[int]:left=0result=[]right=left+kcurrent_max=0while left<right and right<=len(nums)-1:for i in range(left,right):current_max=current_maxif nums[i]>nums[left]:current_max=max(current_max,nums[i])result.append(current_max)left+=1right+=1return resultnums=[1,3,-1,-3,5,3,6,7]
k=3
print(maxSlidingWindow(nums,k))

运行一下,是错误的。列表中数字个数就不对,而且值也不对。应该输出

[3,3,5,5,6,7]

循环次数就搞错了

更正一下循环的内容。奥对了,自己测试的时候要引入List库,就是我第一行的东西,要不然会报错。

from typing import Listdef maxSlidingWindow(nums: List[int], k: int) -> List[int]:left=0result = []for left in range(len(nums) - k + 1):# 确定当前窗口的结束位置right = left + k# 初始化当前窗口的最大值为窗口的第一个元素current_max = nums[left]# 遍历当前窗口中的所有元素,找到最大值for i in range(left, right):# 如果当前元素比当前记录的最大值大,则更新最大值if nums[i] > current_max:current_max = nums[i]# 将当前窗口的最大值添加到结果列表中result.append(current_max)return result# 测试用例
nums=[1,3,-1,-3,5,3,6,7]
k=3
print(maxSlidingWindow(nums,k))

输出结果:[3, 3, 5, 5, 6, 7]

结果是对的,但是这还是暴力解法。不用提交我也知道过不了,哭哭,什么时候我们打暴力选手才能被欣赏(纯发疯)。

换个思路吧老铁。

看了一下题解,大部分都用到了队列。我们先学一下队列的知识吧。

队列(Queue) 是一种先进先出(First-In-First-Out, FIFO)的线性数据结构,元素只能从一端(队尾)添加,从另一端(队首)移除。

队列的特性

  • 先进先出:最早入队的元素最先出队
  • 两端操作:只能在队尾入队,队首出队
  • 顺序访问:元素按入队顺序排列和访问

队列的基本操作

操作描述时间复杂度
enqueue(x)将元素x添加到队尾O(1)
dequeue()移除并返回队首元素O(1)
front()返回队首元素但不移除O(1)
rear()返回队尾元素但不移除O(1)
is_empty()判断队列是否为空O(1)
size()返回队列中元素的个数O(1)

各种队列实现对比

队列类型时间复杂度(入队/出队)空间复杂度优点缺点
顺序队列O(1)/O(n)O(n)实现简单出队效率低,假溢出
链式队列O(1)/O(1)O(n)动态扩容,无溢出需要额外空间存储指针
循环队列O(1)/O(1)O(n)高效利用空间,无假溢出容量固定,实现较复杂
双端队列O(1)/O(1)O(n)两端都可操作实现复杂

关于这个题目,我们可以设置一个队列

使用双端队列存储数组元素的索引(而非元素值)
维护队列中的元素值单调递减:对于新加入的元素,从队尾移除所有小于当前元素的元素,这样可以确保队首元素始终是当前窗口的最大值
当队首元素的索引超出当前窗口范围时,将其从队首移除,即进入下一个窗口
当窗口大小达到k时,开始记录每个窗口的最大值(即队首元素)

def maxSlidingWindow(nums, k):# 准备工作result = []  # 存储结果q = deque()  # 创建一个双端队列for right in range(len(nums)):  # right是当前处理的数的索引# 步骤1:把队列里比当前数小的都移除# 注意:nums[right]是当前数的值# q[-1]是队列里最后一个元素的索引while q and nums[right] >= nums[q[-1]]:q.pop()  # 从队尾移除# 步骤2:把当前数的索引加入队列q.append(right)# 步骤3:移除窗口外的元素# 窗口左边界 = right - k + 1# 如果队列第一个元素的索引 < 左边界,就移除它while q[0] <= right - k:q.popleft()  # 从队首移除# 步骤4:当窗口大小达到k时,记录结果if right >= k - 1:# 队列第一个元素就是当前窗口的最大值的索引result.append(nums[q[0]])return result

运行通过啦!

三、本题收获

注意在初始化时,列表result如果初始化为0,即定义result为int类型,这就无法使用append函数,应该初始化为空列表。

再就是队列存储的是索引,这样会避免重复。


总结

        只会打暴力,基础一团糟,明天再学吧老铁,别真学会了。

http://www.dtcms.com/a/345053.html

相关文章:

  • 利用DeepSeek编写从xlsx数据源调用duckdb执行已保存的查询SQL语句,并把查询结果保存到xlsx文件的程序
  • 电机驱动实现插补算法之脉冲和方向接收(以stm32主控为例)
  • 飞算JavaAI开发助手: 新手开发任务管理系统实战流程
  • STM32G4-比较器
  • Autosar之Com模块
  • Redis面试精讲 Day 27:Redis 7.0/8.0新特性深度解析
  • 基于STM32+Python+MySQL实现在线温度计设计和制作
  • 【高等数学笔记-极限(4)】极限的运算法则
  • 大麦盒子DM4036-精简固件包及教程
  • Vue2+Vue3前端开发_Day7
  • [TG开发]部署机器人
  • Java多线程编程与锁机制全解析(覆盖Java到Spring)
  • 从0到1打造一台机器人走起来
  • 技术解读|MatrixOne高效 CDC:基于快照的分布式数据库优化方案
  • AI如何赋能财务分析:1份财务报表录入从数小时到5分钟
  • 声网SDK更新,多场景抗弱网稳定性大幅增强
  • 制造企业用档案宝,档案清晰可查
  • ArrayList线程不安全问题及解决方案详解
  • AI:业务驱动与技术赋能:企业智能化应用的双向进化深度指南
  • 红酒数据集预处理实战:缺失值处理的 5 种打开方式,从入门到进阶一步到位
  • vue-admin-template权限管理
  • 信创认证是什么?怎么报考?
  • 特级资质信息化迎检核心流程经验分享
  • Pod控制器详解
  • STM32之ADC详解
  • [系统架构设计师]大数据架构设计理论与实践(十九)
  • ​维基框架 (Wiki Framework) 1.1.0 版本发布​ 提供多模型AI辅助开发
  • TNS(ORACLE)协议分析
  • [硬件电路-162]:PID参数受哪些因素影响?
  • 【Redis】缓存和分布式锁