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

子串-滑动窗口的最大值

滑动窗口的最大值

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

输入:整型数组,最大值k
输出:返回数组
思路:定长双指针,滑动窗口,不是很合理

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //定义结果数组
        int[] result = new int[nums.length - k + 1];
        //定义局部最大值
        int tmpMax = 0;
        for(int i = 0;i < k;i++){
            tmpMax = Math.max(tmpMax,nums[i]);
        }
        result[0] = tmpMax;
        //定义双指针
        int l = 0;
        int r = k - 1;
        while(r < nums.length){
            tmpMax = Math.max(tmpMax,nums[r]);
            result[l] = tmpMax;
            l++;
            r++;
        }
        return result;
    }
}

当k为1时,结果错误,移动删除掉的可能刚好是最大值,所以不能通过此方法来进行计算


二刷

  1. 使用优先队列进行维护堆顶元素,先将前k个元素加入到队列中,然后一次遍历剩下的元素,进行堆顶的维护
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //定义优先队列
        PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<>(){
            public int compare(int[] pair1, int[] pair2){
                //降序排列
                return pair1[0] != pair2[0] ? pair2[0] - pair1[0] : pair2[1] - pair1[1];
            }
        });
        int n = nums.length;
        //将前k个数组元素加入优先队列
        for(int i = 0; i < k; i++){
            pq.offer(new int[]{nums[i], i});
        }
        //结果数组
        int[] result = new int[n - k + 1];
        result[0] = pq.peek()[0];
        //然后进行后面的遍历
        for(int i = k; i < n; i++){
            //每次都加入到优先队列
            pq.offer(new int[]{nums[i], i});
            //维护堆顶元素
            while(pq.peek()[1] <= i - k){
                pq.poll();
            }
            result[i - k + 1] = pq.peek()[0];
        }
        return result;
    }
}

注意这里细节处理,什么时候将堆顶元素poll,while(pq.peek()[1] <= i - k),还有将数组的索引位置也维护在优先队列中
但是此时的算法执行用时有点高
在这里插入图片描述
2. 使用单调队列,主要在于这段

while(!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]){
                queue.pollLast();
            }

的理解

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        Deque<Integer> queue = new LinkedList<>();
        //将前k个加入双端队列
        for(int i = 0; i < k; i++){
            while(!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]){
                queue.pollLast();
            }
            queue.offer(i);
        }
        int[] result = new int[n - k + 1];
        result[0] = nums[queue.peekFirst()];
        for(int i = k; i < n; i++){
            while(!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]){
                queue.pollLast();
            }
            queue.offer(i);
            while(queue.peekFirst() <= i - k){
                queue.pollFirst();
            }
            result[i - k + 1] = nums[queue.peekFirst()];
        }
        return result;
    }
}

相关文章:

  • 科研软件分享
  • AI agents系列之全从零开始构建
  • 批处理(Batch Processing)的详解、流程及框架/工具的详细对比
  • 前端工程化之自动化构建
  • .NET MCP 文档
  • 多模态思维链(Multimodal Chain of Thought, MCoT)六大技术支柱在医疗领域的应用
  • OpenCv--换脸
  • 群辉搭建静态网站
  • 基于 Qt 的 BMP 图像数据存取至 SQLite 数据库的实现
  • WSL2 配置和离线安装linux系统。
  • 基础算法篇(5)(蓝桥杯常考点)—动态规划(C/C++)
  • PyCharm 开发工具 修改字体大小及使用滚轮没有反应
  • 【Wasserstein-1 距离】
  • Spring Boot + ShardingSphere 分库分表实战:电商订单场景案例
  • cline 提示词工程指南-架构篇
  • 美团即时零售大动作,将独立的闪购将会改变什么?
  • UE5 设置父物体和解除父子关系(移除子物体)
  • 磁珠详解:特性参数、选型方法、厂商对比及与电感的区别
  • 【动手学强化学习】番外6-MAPPO应用框架学习
  • QT开发之Mysql数据库(一)
  • 专访|伊朗学者:美伊核谈不只是改革派立场,但伊朗不信任美国
  • 关键词看中国经济“一季报”:稳,开局良好看信心
  • 合同约定拿850万保底利润?重庆市一中院:约定无效,发回重审
  • 我国首次实现地月距离尺度卫星激光测距
  • 华夏银行青岛分行另类处置不良债权,德州近百亩土地被神奇操作抵押贷款
  • 神舟二十号载人飞船与空间站组合体完成自主快速交会对接