LeetCode 239:滑动窗口最大值 思考分析

给定一个数组 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 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

提示:

1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
1 <= k <= nums.length

暴力求解:超时

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int maxnum=-10001;vector<int> result;int n= nums.size();//1、如果k> = nums.size,   if(k>=n){for(int i=0;i<n;i++){if(nums[i]>=maxnum) maxnum=nums[i];}result.push_back(maxnum);return result;}//2、如果k<nums.sizeelse{int left=0;int right=0;for(left = 0;left<=n-k;left++){//更新左右边界right=left+k-1;//更新最小值maxnum=-10001;for(int x=left;x<=right;x++){if(nums[x]>=maxnum) maxnum=nums[x]; }result.push_back(maxnum);}return result;}}
};

优化思路:
可以想到暴力方法肯定是有时间浪费的,在滑窗移动的时候,滑窗内插入一个新值,消失了一个旧值,有k-1个值仍然保留着。
我们只需要比较一下新插入的值和旧的k-1个值中的最大值,将得到的最大值赋给结果数组就可以了。
一开始我想的是用两个容量为2的数组,分别存放第一大的数值和它的下标,第二大的数值和它的下标,但是在推导的时候发现一个问题:
错误代码,具体疑问见代码注释:

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int maxnum[2]={-10001,-10001};      //存储当前滑窗内第一大和第二大的数值int index[2]={0,0};                 //存储当前滑窗内第一大和第二大的数值的下标vector<int> result;int n= nums.size();if(k*n==0) return result;//1、如果k> = nums.size,   if(k>=n){for(int i=0;i<n;i++){if(nums[i]>=maxnum[0]) maxnum[0]=nums[i];}result.push_back(maxnum[0]);return result;}//2、如果k<nums.sizeelse{int left=0;int right=0;//将前k个数进行装载for(int i=0;i<k;i++){//nums[i]比第一大还大,更新第一大if(nums[i]>=maxnum[0]){maxnum[0]=nums[i];   //第一大装载完毕index[0]=i;  } //第二大的范围:大于等于旧的第二大,小于等于新的第一大,并且不能是第一大的数if(nums[i]>=maxnum[1] && nums[i]<=maxnum[0] && index[0]!=i){maxnum[1]=nums[i];   //第二大装载完毕index[1]=i;  }}left=1;//从第k+1个数开始for(right = k;right<n;right++,left++)  {//如果移动的时候将最大值抛弃if(index[0]<left){//比较第二大的值和新插入的值的大小,获取最大值//如果第二大值比新插入值大,则第二大值变为最大值,但是新插入的值不一定是第二大值//所以我们需要构建一个从大到小排列的双端队列!if(maxnum[1]>=)}result.push_back(maxnum);}return result;}}
};

发现需要构建一个从大到小排列的双端队列
1、新的数入队列,并按照其大小排列,然后将比它小的数全部出队列(因为我们需要的是最大值,只要队列中有数比新入队列的数要小就说明它们绝对不可能是最大值,最大值最起码也是大于等于新入队列的数)。
2、观察队首(数值最大)的索引值是否在[left,right]之间,如果不在就出队列,直到队首索引值满足在[left,right]之间

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;int n= nums.size();if(n==0 ||k==0) return result;if(k>=n){auto maxPosition = max_element(nums.begin(), nums.end());result.push_back(*maxPosition);return result;}//2、如果k<nums.sizeelse{int left=0;int right=0;// 双向队列 保存当前窗口最大值的数组位置 保证队列中数组位置的数值按从大到小排序deque< int> Dq;// 遍历nums数组for(int i = 0;i < n;i++){// 保证从大到小 如果前面数小则需要依次弹出,直至满足要求//如果队尾的元素小于Nums[i],队尾元素出队列while(Dq.size() && nums[Dq.back()] <= nums[i]){Dq.pop_back();}// 将当前数组下标入队列Dq.push_back(i);if(i>=k-1){// 判断当前队列中队首是否有效,如果队首小于左边界,则将队首出队列,直到队首元素符合要求while(Dq.size() && Dq.front() <= i-k){Dq.pop_front(); }result.push_back(nums[Dq.front()]);}}return result;}}
};

虽然AC了,但是效率不高,不过基本思路是符合大众的:
在这里插入图片描述
不过上述的写法仍然有些不简洁,这里贴一下比较简洁的写法:
https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
官方给出的dp思路,还得理解理解
https://leetcode-cn.com/problems/sliding-window-maximum/submissions/

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int n = nums.size();vector<int> output(n-k+1,0);vector<int> left(n,0);vector<int> right(n,0);left[0]=nums[0];right[n-1]=nums[n-1];for(int i = 1;i<n;i++){if(i%k == 0) left[i]=nums[i];else left[i]=max(left[i-1],nums[i]);int j = n-i-1;if((j+1)%k == 0) right[j]=nums[j];else right[j]=max(right[j+1],nums[j]);}for(int i = 0;i < n-k+1;i++)output[i] = max(left[i+k-1],right[i]);return output;}
};

为什么:两数组一起可以提供两个块内元素的全部信息。
考虑从下标 i 到下标 j的滑动窗口。 根据定义,right[i] 是左侧块内的最大元素, left[j] 是右侧块内的最大元素。因此滑动窗口中的最大元素为 max(right[i], left[j])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机论文范文1500,电子商务毕业论文范文1500字

电子商务毕业论文范文1500字时间稍纵即逝&#xff0c;充满意义的大学生活即将结束&#xff0c;毕业前要通过最后的毕业论文&#xff0c;毕业论文是一种有计划的检验学生学习成果的形式&#xff0c;那么问题来了&#xff0c;毕业论文应该怎么写&#xff1f;下面是小编为大家整理…

五、规则组织的衍生组织——纬山形组织数学模型的建立

基础概念公式推到可参考该专栏下的前几篇博文。 纬山形组织图&#xff1a; 观察可知&#xff1a;纬山形组织图下半部分是右斜组织&#xff0c;上半部分是左斜组织。右斜和左斜按照垂直方向进行排列。 该图是一个2上3下2上1下(从最下面一行从左往右观看) 特点&#xff1a;每一…

剑指 Offer 57 - II. 和为s的连续正数序列 思考分析

输入一个正整数 target &#xff0c;输出所有和为 target 的连续正整数序列&#xff08;至少含有两个数&#xff09;。 序列内的数字由小到大排列&#xff0c;不同序列按照首个数字从小到大排列。 示例 1&#xff1a; 输入&#xff1a;target 9 输出&#xff1a;[[2,3,4],[4…

六、规则组织的衍生组织——纬向破斜组织数学模型的建立

基础概念公式推到可参考该专栏下的前几篇博文。 纬向破斜组织图&#xff1a; 下半部分(从左往右)&#xff1a;&#xff0c;3上2下2上1下&#xff0c;右斜&#xff0c;飞数为1 上半部分(从下往上)&#xff1a;&#xff0c;2上2下1上3下。左斜&#xff0c;飞数为-1 通过分析可…

数据结构与算法2——数组

数组是应用最广泛的数据存储结构。它被植入到大部分编程语言中。大部分数据结构都有最基本的四个操作&#xff1a;插入、删除、查找、修改。对于这四种操作每一种数据结构都有相应的算法。算法和数据结构因此就是非常紧密的相联系的。 1 数组例子 …

LeetCode 167. 两数之和 II - 输入有序数组 思考分析

目录1、暴力&#xff0c;超时2、双指针滑动窗口条件限制 AC3、观看题解&#xff08;吸取他人经验&#xff09;1、二分查找2、双指针3、双指针二分查找给定一个已按照升序排列 的有序数组&#xff0c;找到两个数使得它们相加之和等于目标数。 函数应该返回这两个下标值 index1 …

敏捷开发用户故事系列之七:用户故事与MVC

这是用户故事系列的第七篇。&#xff08;之一&#xff0c;之二&#xff0c;之三&#xff0c;之四&#xff0c;之五&#xff0c;之六&#xff0c;之七&#xff0c;之八&#xff0c;之九&#xff09;用户故事和MVC没有关系&#xff0c;因为MVC是实现方法&#xff0c;因此在思考用…

七、规则组织的衍生组织——菱形斜纹组织数学模型的建立

基础概念公式推到可参考该专栏下的前几篇博文。 菱形斜纹组织图&#xff1a; 分析&#xff1a;首先3上2下2上1下&#xff0c;飞数为1&#xff0c;右斜。kw8表示从左下角开始往上数8格为纬峰所在位置&#xff1b;kj8表示从左上角开始往右数8格为经峰所在位置。 这样就将菱形斜…

显卡测试软件毛毛虫,超龙超龙,与众不同,顶流配备,散热一流,3070Ti超龙旗舰版评测...

可能大家都没想到此次显卡荒会持续近一年&#xff0c;还是出现国家级干涉才将这股“歪风”刹住了。而且也仅仅算是刹住了大陆的速度&#xff0c;主要踩死刹车的应该就是黄大厨。他从5月初推出的新核心就采取了出厂即锁算力的做法&#xff0c;但是即便如此&#xff0c;那些看着高…

八、非规则组织分析及其数学模型——平纹变化组织

非规则组织顾名思义&#xff0c;无法通过一个数学模型来描述所有的非规则组织、对于每一个具体的非规则组织而言&#xff0c;其也有一定的规律性可循&#xff0c;即可通过分析每一个具体的非规则组织的组织点运动规律来建立相应的数学模型。 一、平纹变化组织 平纹变化组织即…

怎么看xp计算机是32位还是64位,教你查看XP系统的不同32位还是64位详细的步骤

电脑中使用的不同的版本如果安装一些大型的游戏的时候都是有技巧来实现的&#xff0c;那在XP电脑中想要知道的对于不同的32位还是64位的版本的文件操作的时候新手是怎么知道自己安装的软件的版本呢&#xff0c;今天小编就来跟大家分享一下教你查看XP系统的不同32位还是64位详细…

LeetCode 27.移除元素 思考分析

题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长…

九、非规则组织分析及其数学模型——曲线斜纹组织

曲线斜纹组织图&#xff1a; 因为其形状酷似抛物线&#xff0c;抛物线又是曲线中的一种&#xff0c;故称为曲线斜纹组织。 特点&#xff1a;1&#xff0c;每一根经纱上的组织点运动规律不变 2&#xff0c;飞数是变化的&#xff0c;故也称为变飞数组织 飞数满足的两个条件&…

计算机公式column,函数公式的左膀右臂:ROW、COLUMN函数知多少

一个公式生成乘法口诀表演示的公式中用到了两个函数&#xff1a;ROW和COLUMN&#xff0c;这两个函数的用途非常广泛&#xff0c;可以配合其他函数实现很多功能(尤其是和VLOOKUP函数)&#xff0c;另外和这两个函数相似的还有ROWS和COLUMNS函数&#xff0c;也顺便介绍下。函数说明…

apache2.4.x三种MPM介绍

三种MPM介绍 Apache 2.X 支持插入式并行处理模块&#xff0c;称为多路处理模块&#xff08;MPM&#xff09;。在编译apache时必须选择也只能选择一个MPM&#xff0c;对类UNIX系统&#xff0c;…

LeetCode 15. 三数之和 思考分析(双指针解)

目录初解&#xff1a;未考虑去重二解&#xff1a;未考虑去重位置三解&#xff1a;AC题目&#xff1a;给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有满足条件且…

十、非规则组织分析及其数学模型——锯齿形斜纹组织

锯齿形斜纹组织图&#xff1a; 分析&#xff1a; 前半齿长度k&#xff0c;表示山谷到山峰的列数&#xff0c;也就是锯齿的宽度&#xff1b; 锯齿飞数s&#xff0c;表示山峰到山峰的行数&#xff0c;也就是锯齿的高度。 起始点相差4格&#xff0c;也就是第一部分整体向上移动…

十一、非规则组织分析及其数学模型——芦席斜纹组织

芦席斜纹组织&#xff1a; 该组织是由左斜和右斜有机的结合在一块的&#xff0c;因为其外观酷似芦席故称之为芦席斜纹组织。 织物组织效果&#xff1a; 所需参数&#xff1a; 其基层组织采用双面加强型斜纹&#xff0c;即分子和分母是相同的组织点&#xff0c;例如2上2下(2个经…

LeetCode 18. 四数之和 思考分析(双指针解)

目录需要注意的几点1、去除剪枝操作2、去重操作的细节code以及效果&#xff1a;题目给定一个包含 n 个整数的数组 nums 和一个目标值 target&#xff0c;判断 nums 中是否存在四个元素 a&#xff0c;b&#xff0c;c 和 d &#xff0c;使得 a b c d 的值与 target 相等&#…

图解DotNet框架之一:编译与执行引擎(上)

众所周知,DotNet框架是非常庞大的,光项目创建时的种类就有WPF,WCF,WF这三种最新的技术,还有以前的Web,WinForm,Service,Mobile等等. 这么复杂和庞大的框架,用文字来描述是远远不够的,所以我准备写一系列图文并茂的文章,把我所知道的所有Net框架中的东西全部串联起来,希望可以给…