「LeetCode」剑指 Offer 59 - I. 滑动窗口的最大值
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目:剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)
前言✔:
算法,对于前端人来说既熟悉又陌生,熟悉的是每个前端er都要学习算法来应对面试、工作和考试,陌生的是我们平时在工作中用到算法的地方并不会很多。所以,我们一直想问算法对于前端来说到底重不重要。
答案是肯定的,N.Wirth (沃斯)说过,“程序 = 算法 + 数据结构” 当然并不是说我们掌握了数据结构和算法就一定能写出好程序,好比作文 = 语法 + 词语也并不代表掌握了后者就能写出好作文。
而重点其实是你不会数据结构+算法就很难写出好程序,最重要的是在阅读一些优质项目源码的时候我们很难看得懂作者的意图,这样我们的视野就会被限制。
计算机科学的灵魂之一就是算法,所以如果我们想要更上一层楼就必不可少的需要学习并且掌握算法和数据结构
如有帮助,请点个赞,我会很开心 😊
题目🚩
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
难度: 中等
示例:
输入:
8 3
1 3 -1 -3 5 3 6 7
输出:
3 3 5 5 6 7
解题思路
暴力:
- 定义窗口大小k
- 之后通过循环求出窗口最大值
- 将窗口移动,重复
2操作 这样出来的程序时间复杂度是O(k*n)
通过队列优化:
-
定义窗口大小k
-
创建一个队列
-
逐个扫描每一个数,
if下一个将要扫描的数大于队列中后n个数,则将后n个数去掉,把将要扫描的数插入队列else把将要扫描的数加入队尾,if队头的位置在窗口之外将队头出对 -
当扫描的数据个数等于窗口大小的时候开始输出队头,这个时候队头就是这个窗口的最大值
优化算法图解 🎁
现在我重新给出一个比较好举例子的案例
输入:
5 2
1 3 -1 5 2
这是逐个扫描数据时我们队列的数据变化,下面逐个解析过程。
- a[0], 队列没有元素,直接插入即可
- a[1], 队列只有 1 这个数据,比a[1]小,删掉a[0]插入a[1],此时扫描的数据两已经等于窗口大小,所以直接输出队头
- a[2], 队列有 3 这个数据,队列中没有数据比a[2]小,直接插入队尾,并且输出队头
- a[3], 队列有 3,1 两个数据,但是数据 3 已经在窗口之外,将 3 出队,此时没有比a[3]小的数所以直接插入队尾,并且输出队头
第五个步骤留给读者来写吧,相信你看到这里已经理解这个算法了,其实就是一个单调队列。
代码🔥
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q ;
vector<int> C;
int hh = 0, tt = -1;
for(int i = 0; i < nums.size(); i++) {
if(hh <= tt && i - k + 1 > q[hh]) hh++;
while(hh <= tt && nums[i] > nums[q[tt]]) tt--;
q[++tt] = i;
++tt;
if(i - k + 1 >= 0) C.push_back(nums[q[hh]]);
}
return C;
}
};
结束语😉
那么这一期lemon的算法讲解就结束了,如果希望进行探讨、一起学习前端或者瞎折腾,欢迎添加微信gyjmy2517(备注来意)
如有帮助,请支持一下点一个赞吧🎈