day13part01|Leetcode239.滑动窗口最大值

文章介绍了如何通过自定义单调队列实现LeetCode题目239滑动窗口中的最大值查找。作者详细解释了单调队列的结构和方法(pop,add,front),以及在主函数中如何运用这些方法来动态求解滑动窗口内的最大值。
摘要由CSDN通过智能技术生成

Leetcode239 滑动窗口

这题真的好难啃第一遍读,已经废掉了脑细胞

今天就先跟着视频及答案理解敲一遍,写了思路如下:


import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

//leetcode submit region begin(Prohibit modification and deletion)
class Myqueue{
    Deque<Integer> deque = new LinkedList<>();
    void poll(int val){
        //______________________
        //_出口_____________入口__
        if(!deque.isEmpty() && val==deque.peek()){
            deque.poll();
            //如果是等于最大的那个元素即出口元素,直接出队
            //否则不操作
        }
    }
    void add(int val){//保持单调递减
        //______________________
        //_出口_____________入口__
        //添加元素>入口元素;弹出直到小于等于呈单调递减
        while (!deque.isEmpty()&& val>deque.getLast()){
            deque.removeLast();//删除出口处元素
        }
        deque.add(val);
    }
    int peek(){
        return deque.peek();
    }

}

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //剪枝
        if(nums.length == 1){
            return nums;
        }
        //创建结果数组
        int[] res = new int[nums.length-k+1];
        int resindex = 0;
        Myqueue myqueue = new Myqueue();
        for (int i = 0; i < k; i++) {
            myqueue.add(nums[i]);
        }
        res[resindex] = myqueue.peek();
        resindex++;
        for (int i = k; i < nums.length; i++) {
            myqueue.poll(nums[i-k]);
            myqueue.add(nums[i]);
            res[resindex] = myqueue.peek();
            resindex++;
        }
        return res;

    }
}

明天重新看一编应该会有新收获吧


早晨起来把 这一题又写了一次


import java.util.Deque;
import java.util.LinkedList;

//leetcode submit region begin(Prohibit modification and deletion)
class MonQueue{
    Deque<Integer> myqueue = new LinkedList<>();
    void pop(int val){
        if (!myqueue.isEmpty() && myqueue.peek()==val){
            myqueue.pop();//pop是出口处
            //myqueue.peek() 出口位置
        }
    }
    void add(int val){
        //getLast(),removeLast() 都是在入口处查看数值及弹出元素
        //是为了维持队列的单调性,必须为单调递减,所在添加元素时,如果前一个<val ,就需要弹出 再判断  直到元素>val
        while(!myqueue.isEmpty() && myqueue.getLast()<val){
            myqueue.removeLast();
        }
        myqueue.add(val);
    }
    int front(){
        //获取窗口最大元素并返回,即为出口处元素
        return myqueue.peek();
    }
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length == 1){
            return nums;
        }
        int reslength = nums.length-k+1;
        int[] res = new int[reslength];
        int resindex = 0;
        //创建单调队列
        MonQueue monQueue = new MonQueue();
        //初始化滑动窗口  并将对应的最大值加入到res
        for(int i = 0;i < k; i++){
            monQueue.add(nums[i]);
        }
        res[resindex++] = monQueue.front();
        //依次循环滑动窗口
        for(int i = k;i<nums.length;i++){
            //pop对应索引应该从0 - nums.length-k
            monQueue.pop(nums[i-k]);
            monQueue.add(nums[i]);
            res[resindex++] = monQueue.front();
        }
        return res;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

实现思路是:通过使用自己创建单调队列实现滑动窗口获取最大值

1.单调队列类:  包含三个成员函数

  • pop(val) --- val滑动窗口出口位置要输出元素值
    • 如果deque出口位置值与 val 相关且不为空   就弹出
  • add(val) --- val滑动窗口入口位置要添加元素值
    • 使用循环实现  队列入口位置值 < val ----如不符就弹出出口处值直到符合
    • 再进行添加 
  • front() --- 获得出口位置值即窗口最大值

2.主函数内:

  • 剪枝: 如果队列只有一个数  直接返回对应值 退出
  • 创建结果数组 长度 数组长度-滑动窗口长度+1
  • 创建引入 单调队列进行操作
    • 初始化 添加前k个元素 (add);将front 加入结果数组,索引自增
    • for 实现滑动: 执行 pop  add  front ;对应的操作元素 分别是 num[i-k] num[i] 无
  • resturn res;

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据引用\[1\],可以使用暴力解法来求解滑动窗口最大值。具体的做法是,遍历数组,对于每个窗口,使用一个内部循环来找到窗口中的最大值,并将其存储在结果数组中。时间复杂度为O(n*k),其中n为数组长度,k为窗口大小。 根据引用\[2\],还可以使用队列来求解滑动窗口最大值。具体的做法是,使用一个双端队列来维护一个单调递减的窗口。遍历数组,对于每个元素,首先判断队头是否在滑动窗口范围内,如果不在,则将其从队头移除。然后,将当前元素与队尾元素比较,如果当前元素大于队尾元素,则将队尾元素移除,直到队列为空或者当前元素小于等于队尾元素。最后,将当前元素的索引插入队尾。如果滑动窗口的元素个数达到了k个,并且始终维持在窗口中,就将队头元素加入答案数组中。时间复杂度为O(n),其中n为数组长度。 综上所述,可以使用暴力解法或者使用队列来求解leetcode滑动窗口最大值。 #### 引用[.reference_title] - *1* *3* [leetcode239. 滑动窗口最大值](https://blog.csdn.net/kkkkuuga/article/details/124829581)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Leetcode#239. 滑动窗口最大值 (Java解法)](https://blog.csdn.net/paranior/article/details/114890555)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值