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

面试热题(滑动窗口最大值)

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  3  -1  -3  5 [3  6  7]      7

 如果你刚看见这道题你会怎么想?三秒告诉我?3...2...1...,时间到!!!

       首先是滑动窗口,一听到这个名字,我们就应该立刻的想到双指针,双指针这个大方向是错不了,我们再看,要每次取到范围内的最大值,除了最大堆就是优先队列可以做到这件事,接下来我们先用最大堆进行解题

        最大堆就是其实就是一棵树,通过上浮和下浮使得堆顶是最大值或者最小值,Java中默认是最小堆,所以我们如果是想每次取到范围内的最大值,

  PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;//最大值   默认是o1-o2}});
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

需要对堆的比较器进行重写,构造一个最大堆

 

 维护一个一个列表进行最大值的维护

List<Integer> list=new ArrayList<>();
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
        for(int right=0;right< nums.length;right++){if(right<k-1){queue.offer(nums[right]);}else{queue.offer(nums[right]);list.add(queue.peek());queue.remove(nums[left++]);}}

结果,不出意外:

       怎么办?时间超时了怎么办?堆的上浮和下沉确实浪费了大量的时间,所以我们使用另外一种数据结构解决本题(优先队列)

    //维护一个单调队列class MaxQueue{private LinkedList<Integer> queue=new LinkedList<>();//添加public void push(int x){  //队列不为空,队尾元素如果小于当家加入元素,直接扔出去while(!queue.isEmpty()&&queue.getLast()<x){queue.pollLast();}queue.addLast(x);}//删除public void pop(int x){if(x==queue.getFirst()){queue.pollFirst();}}//得到最大值public Integer getMax(){return queue.getFirst();}}

 核心代码:

  int left=0;for(int right=0;right< nums.length;right++){if(right<k-1){window.push(nums[right]);}else{window.push(nums[right]);list.add(window.getMax());window.pop(nums[left++]);}}

结果,不出意外:

 上源代码:

  public int[] maxSlidingWindow(int[] nums, int k) {if(nums==null){return null;}MaxQueue window=new MaxQueue();List<Integer> list=new ArrayList<>();int left=0;for(int right=0;right< nums.length;right++){if(right<k-1){window.push(nums[right]);}else{window.push(nums[right]);list.add(window.getMax());window.pop(nums[left++]);}}return list.stream().mapToInt(Integer::valueOf).toArray();}//维护一个单调队列class MaxQueue{private LinkedList<Integer> queue=new LinkedList<>();//添加public void push(int x){while(!queue.isEmpty()&&queue.getLast()<x){queue.pollLast();}queue.addLast(x);}//删除public void pop(int x){if(x==queue.getFirst()){queue.pollFirst();}}//得到最大值public Integer getMax(){return queue.getFirst();}}

http://www.lryc.cn/news/118790.html

相关文章:

  • 【代码】表格封装 + 高级查询 + 搜索 +分页器 (极简)
  • ant.design 组件库中的 Tree 组件实现可搜索的树: React+and+ts
  • Linux系统编程之信号(上)
  • 23.Netty源码之内置解码器
  • sigmoid ReLU 等激活函数总结
  • RabbitMQ 消息队列
  • PHP实现在线进制转换器,10进制,2、4、8、16、32进制转换
  • 报错 | Spring报错详解
  • PHP最简单自定义自己的框架数据库封装调用(五)
  • 使用Redis来实现点赞功能的基本思路
  • 【黑马头条之app端文章搜索ES-MongoDB】
  • Nginx安装以及LVS-DR集群搭建
  • 后端开发9.商品类型模块
  • spring框架自带的http工具RestTemplate用法
  • 【flink】Checkpoint expired before completing.
  • 【论文阅读】NoDoze:使用自动来源分类对抗威胁警报疲劳(NDSS-2019)
  • 【ARM64 常见汇编指令学习 16 -- ARM64 SMC 指令】
  • uprobe trace多线程mutex等待耗时
  • Linux 和 MacOS 中的 profile 文件详解(一)
  • 不用技术代码,如何制作成绩查询系统?
  • flinksql sink to sr often fail because of nullpoint
  • 达梦数据库:Error updating database. Cause: dm.jdbc.driver.DMException: 数据未找到
  • 电脑怎么查看连接过的WIFI密码(测试环境win11,win10也能用)
  • 处理数据部分必备代码
  • layui 集成 ztree异步加载
  • LeetCode面向运气之Javascript—第27题-移除元素-98.93%
  • 谷歌云 | 电子商务 | 如何更好地管理客户身份以支持最佳的用户体验
  • 行业追踪,2023-08-09
  • 视图、存储过程、函数、触发器
  • 数学建模学习(10):遗传算法