最大值_Leetcode2 | 滑动窗口最大值(Q239)

:)

Sliding Window Maximum

Q 239

今天也是好心情

84778e13821c435ce71e163e682f4bf8.png

Problem Description

··· Difficulty···

You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

Return the max sliding window.

Example 1:

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3

Output: [3,3,5,5,6,7]

Explanation: 

Window position                Max

---------------               -----

[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

 Too Young

很朴素的循环遍历+调用库函数max找最值

也不出意外的TLE了:(

// Javascript版var maxSlidingWindow = function(nums, k) {    let max = [];    for(let i = 0; i < nums.length-k+1; i++){        let tmp = nums.slice(i,i+k);        max.push(Math.max(...tmp));    }    return max;};

代码实现起来真的很快很简单,但TLE也很快的显示了出来T^T

当我点进超时数据时,看傻了...(是我大意了)

a4eadf99fe40e1393cc0c29e1556903f.png

Too Young Too Simple

官方

题解

2

   优先队列

优先队列(Heap)

可实时维护一系列元素中的最大/小值

    对于本题而言,初始时,将 nums 的前k个元素放入优先队列中。每当我们向右移动窗口时,我们就可以把一个新的元素放入优先队列中,此时堆顶的元素就是堆中所有元素的最大值。然而这个最大值可能并不在滑动窗口中,在这种情况下,这个值在数组 nums 中的位置出现在滑动窗口左边界的左侧。因此,当我们后续继续向右移动窗口时,这个值就永远不可能出现在滑动窗口中了,我们可以将其永久地从优先队列中移除。

    我们不断地移除堆顶的元素,直到其确实出现在滑动窗口中。此时,堆顶元素就是滑动窗口中的最大值。为了方便判断堆顶元素与滑动窗口的位置关系,我们可以在优先队列中存储二元组(num,index),表示元素num在数组中的下标为index。

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        int n = nums.size();        priority_queueint,         for (int i = 0; i < k; ++i) {            q.emplace(nums[i], i);        }        vector<int> ans = {q.top().first};        for (int i = k; i < n; ++i) {            q.emplace(nums[i], i);            while (q.top().second <= i - k) {                q.pop();            }            ans.push_back(q.top().first);        }        return ans;    }};

e5c03074fa38b69bf804ca52a4adf8bf.gif

时间复杂度 O(nlogn)

最坏情况下,数组nums 中的元素单调递增,那么最终优先队列中包含了所有元素,没有元素被移除。由于将一个元素放入优先队列的时间复杂度为O(logn),因此总时间复杂度为O(nlogn)。

空间复杂度 O(n)

官方

题解

3

   单调队列

“优先队列方法的优化版

    由于我们需要求出的是滑动窗口的最大值,如果当前的滑动窗口中有两个下标i和j,其中i在j的左侧(i

    当滑动窗口向右移动时,只要i还在窗口中,那么j一定也还在窗口中,这是i在j的左侧所保证的。因此,由于 nums[j] 的存在,nums[i] 一定不会是滑动窗口中的最大值了,我们可以将nums[i] 永久地移除。

    因此我们可以使用一个队列存储所有还没有被移除的下标。在队列中,这些下标按照从小到大的顺序被存储,并且它们在数组nums 中对应的值是严格单调递减的。因为如果队列中有两个相邻的下标,它们对应的值相等或者递增,那么令前者为i,后者为j,就对应了上面所说的情况,即nums[i] 会被移除,这就产生了矛盾。

    当滑动窗口向右移动时,我们需要把一个新的元素放入队列中。为了保持队列的性质,我们会不断地将新的元素与队尾的元素相比较,如果前者大于等于后者,那么队尾的元素就可以被永久地移除,我们将其弹出队列。我们需要不断地进行此项操作,直到队列为空或者新的元素小于队尾的元素。

    由于队列中下标对应的元素是严格单调递减的,因此此时队首下标对应的元素就是滑动窗口中的最大值。但与方法一中相同的是,此时的最大值可能在滑动窗口左边界的左侧,并且随着窗口向右移动,它永远不可能出现在滑动窗口中了。因此我们还需要不断从队首弹出元素,直到队首元素在窗口中为止。

    为了可以同时弹出队首和队尾的元素,我们需要使用双端队列。满足这种单调性的双端队列一般称作「单调队列」。

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        int n = nums.size();        deque<int> q;        for (int i = 0; i < k; ++i) {            while (!q.empty() && nums[i] >= nums[q.back()]) {                q.pop_back();            }            q.push_back(i);        }        vector<int> ans = {nums[q.front()]};        for (int i = k; i < n; ++i) {            while (!q.empty() && nums[i] >= nums[q.back()]) {                q.pop_back();            }            q.push_back(i);            while (q.front() <= i - k) {                q.pop_front();            }            ans.push_back(nums[q.front()]);        }        return ans;    }};

e5c03074fa38b69bf804ca52a4adf8bf.gif

时间复杂度 O(nlogn)

最坏情况下,数组nums 中的元素单调递增,那么最终优先队列中包含了所有元素,没有元素被移除。由于将一个元素放入优先队列的时间复杂度为O(logn),因此总时间复杂度为O(nlogn)。

空间复杂度 O(n)

官方

题解

4

 分块+预处理

“类似稀疏表(Sparse Table)的一种思路

    可以将数组 nums 从左到右按照 k 个一组进行分组,最后一组中元素的数量可能会不足 k 个。如果我们希望求nums[i]到nums[i+k−1] 的最大值,就会有两种情况:

  • 如果i是k的倍数,那么nums[i]到nums[i+k−1]恰好是一个分组。我们只要预处理出每个分组中的最大值,即可得到答案;

  • 如果i不是k的倍数,那么nums[i]到nums[i+k−1]会跨越两个分组,占有第一个分组的后缀以及第二个分组的前缀。假设j是k的倍数,并且满足i

f2dbe997a63a661326891c421e86a429.png

需要注意在递推suffixMax[i] 时需要考虑到边界条件 suffixMax[n−1]=nums[n−1],而在递推 prefixMax[i] 时的边界条件prefixMax[0]=nums[0] 恰好包含在递推式的第一种情况中,因此无需特殊考虑。

在预处理完成之后,对nums[i] 到nums[i+k−1] 的所有元素,如果i不是k的倍数,那么窗口中的最大值为 suffixMax[i]和prefixMax[i+k−1] 中的较大值;如果i是k的倍数,那么此时窗口恰好对应一整个分组,suffixMax[i]和prefixMax[i+k−1] 都等于分组中的最大值,因此无论窗口属于哪一种情况

max{suffixMax[i],prefixMax[i+k−1]}

即为所求

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        int n = nums.size();        vector<int> prefixMax(n), suffixMax(n);        for (int i = 0; i < n; ++i) {            if (i % k == 0) {                prefixMax[i] = nums[i];            }            else {                prefixMax[i] = max(prefixMax[i - 1], nums[i]);            }        }        for (int i = n - 1; i >= 0; --i) {            if (i == n - 1 || (i + 1) % k == 0) {                suffixMax[i] = nums[i];            }            else {                suffixMax[i] = max(suffixMax[i + 1], nums[i]);            }        }        vector<int> ans;        for (int i = 0; i <= n - k; ++i) {            ans.push_back(max(suffixMax[i], prefixMax[i + k - 1]));        }        return ans;    }};

e5c03074fa38b69bf804ca52a4adf8bf.gif

时间复杂度 O(n)

空间复杂度 O(n)

100a66ca59d9d375519e965227acb22d.png

—END—

题目和题解均源自LEETCODE :)

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

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

相关文章

PCDN实现flash无延时直播的技术原理与优点

摘要&#xff1a; PCDN是以P2P技术为基础&#xff0c;通过挖掘利用边缘网络海量碎片化闲置资源而构建的内容分发网络&#xff0c;它具有低成本、高品质的特点&#xff0c;十分适用于视频直播这一业务场景。针对直播中延时的情况&#xff0c;PCDN也进行了一系列优化&#xff0c;…

CDN新品发布:阿里云SCDN安全加速开放公测

摘要&#xff1a; SCDN(SecureCDN)安全加速产品是CDN推出的一款集合安全能力的内容加速服务&#xff0c;用户就近取得所需内容解决因分布、带宽、服务器性能带来的访问延迟问题&#xff0c;提升网站访问速度。同时防护DDoS&#xff0c;CC&#xff0c;Web应用攻击&#xff0c;恶…

美企调查华为设备安全性,华为发长文质疑;摩根大通预计苹果2020年将推5G iPhone;谷歌拟联手Dish成立美国第四大运营商...

戳蓝字“CSDN云计算”关注我们哦&#xff01;嗨&#xff0c;大家好&#xff0c;重磅君带来的【云重磅】特别栏目&#xff0c;如期而至&#xff0c;每周五第一时间为大家带来重磅新闻。把握技术风向标&#xff0c;了解行业应用与实践&#xff0c;就交给我重磅君吧&#xff01;重…

实现mvcc_MySQL 的多版本并发控制(MVCC) 是干啥的?

点击蓝色“架构文摘”关注我哟加个“星标”&#xff0c;每天上午 09:25&#xff0c;干货推送&#xff01;来源&#xff1a;https://segmentfault.com/a/1190000037557620作者&#xff1a;白菜1031一、什么是多版本并发控制多版本并发控制 技术的英文全称是 Multiversion Concur…

网站访问速度提升200%以上,阿里云虚拟主机支持PHP最新版本

摘要&#xff1a; 日前&#xff0c;阿里云虚拟主机推出了新功能&#xff0c;支持PHP的最新版本 7.0和7.1&#xff0c;并支持用户在多个不同PHP版本之间切换。 PHP 作为最好的Web编程语言&#xff0c;最新版本已经更新到了7.0和7.1。阿里云作为国内虚拟主机的领头羊&#xff0c;…

2019年6月 阿里技术面试题集锦(28道含答案)

戳蓝字“CSDN云计算”关注我们哦&#xff01;想要入职大厂可谓是千军万马过独木桥。要通过层层考验&#xff0c;刷题肯定是必不可少的。为帮助开发者们提升面试技能、有机会入职阿里&#xff0c;云栖社区特别制作了这个专辑——阿里巴巴资深技术专家们结合多年的工作、面试经验…

一键清理网站木马文件,从此网站拥有专属保镖 ——阿里云虚拟主机推出木马查杀功能...

摘要&#xff1a; 近日&#xff0c;阿里云推出了云虚拟主机网站木马查杀的新功能&#xff0c;十分适合对网站安全不了解、不熟悉的用户&#xff0c;或网站出现挂马情况不清楚如何处理的用户。 阿里云表示&#xff0c;此次网站木马查杀功能是阿里云安骑士专为虚拟主机推出的安全…

每天自动备份网站数据,发现问题一键恢复 ——阿里云虚拟主机推出网站数据自动备份功能...

摘要&#xff1a; 近日&#xff0c;阿里云宣布推出虚拟主机网站自动备份功能&#xff0c;可自动备份用户的网站和数据库数据至单独的备份区域&#xff0c;用户可随时恢复前三天的网站和数据库的数据。一旦出现意外或者数据丢失情况&#xff0c;可将损失降低到最低。 数据是用户…

如何快速下载CentOS7镜像

在centOS官网下载很慢&#xff0c;因此记录哪里下载比较快&#xff0c;其实就是 开源镜像网站网址阿里巴巴开源镜像站https://opsx.alibaba.com/mirror网易163开源镜像网站http://mirrors.163.com/ 下载entOS7步骤&#xff1a; 以阿里巴巴开源镜像网站作演示&#xff1a; 1.进…

pypi.python.org_在Pypi上发布自己的Python包

使用Python编程的都知道&#xff0c;Python的包安装非常的方便&#xff0c;一般都是可以pip来安装搞定&#xff1a;sudo pip install 最近因为项目上的需要&#xff0c;发布了一个自己的pypi Python包&#xff0c;这里我大致分享如何发布自己的Pypi包一般过程。打包工作主要依赖…

20大5G关键技术

戳蓝字“CSDN云计算”关注我们哦&#xff01;来源 | 北京物联网智能技术应用协会5G网络技术主要分为三类&#xff1a;核心网、回传和前传网络、无线接入网。核心网核心网关键技术主要包括&#xff1a;网络功能虚拟化&#xff08;NFV&#xff09;、软件定义网络&#xff08;SDN&…

AliOS Things网络连接技术概述

摘要&#xff1a; AliOS Things具有非常丰富的连接组件和能力&#xff0c;主要包括: 自组织网络协议(uMesh)&#xff0c; 套接字适配层(SAL)&#xff0c;TCP/IP网络协议栈(LwIP)和连接协议(WiFi,BLE, LoRaWAN, GPRS和NB-IoT等) AliOS Things 是 AliOS 家族旗下的、面向 IoT 领域…

SCDN的抗CC攻击和抗DDoS攻击防护是什么?

摘要&#xff1a; 阿里云SCDN提供的一整套加速和安全的解决方案。目前SCDN抗CC防护保底6万QPS&#xff0c;最高到100万QPS。另可定制最高达250万QPS防护。而抗DDoS保底防护20Gbps&#xff0c;最高到300Gbps。另可定制最高达600Gbps防护。 CC攻击是什么&#xff1f; CC攻击是 D…

命令启动jar包_java项目打jar包,一句命令搞定

jar命令格式&#xff1a;jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名其中{ctxu}这四个参数必须选选其一。[v f m e 0 M i ]是可选参数&#xff0c;文件名也是必须的。所有的参数说明&#xff1a;-c 创建一个jar包-t 显示jar中的内容列表-x 解压jar包-u 添加文件到jar包中-…

Linux:查询当前进程或线程的资源使用情况

目录 一、/proc/[PID]/下的各个文件1、proc简介2、/proc/[PID]/详解 二、通过Linux API获取当前进程或线程的资源使用情况1、getrusage2、sysinfo3、times 在工作中&#xff0c;我们排除app出现的一些性能/资源问题时&#xff0c;通常要先知道当前app的资源使用情况&#xff0c…

如何使用API提交转码任务?

摘要&#xff1a; 当常规的转码工作流无法满足用户的场景时&#xff0c;需用户自己判断业务逻辑&#xff0c;并使用API提交转码任务。例如&#xff1a;并不是所有的视频都需要转码&#xff0c;不同视频需要设置不同的转码配置。本文将介绍API提交转码任务的方法。 当常规的转码…

微博短视频千万级高可用、高并发架构如何设计?

作者&#xff1a;刘志勇&#xff0c;本文来自新浪微博视频平台资深架构师刘志勇在 LiveVideoStackCon 2018 讲师热身分享&#xff0c;并由 LiveVideoStack 整理而成。 本文从设计及服务可用性方面&#xff0c;详细解析了微博短视频高可用、高并发架构设计中的问题与解决方案。…

三点估算pmp_【每日一练】PMP项目管理专业资格认证考试练习题(十)

听说99%的同学都来这里充电吖【习题】1.客户提出的一项需求&#xff0c;将变更项目范围。如果变更控制委员会批准需求&#xff0c;执行变更的成本将影响项目的预算。如果这项需求获得批准&#xff0c;项目经理应该考虑从下列哪一项储备中申请资金&#xff1f;A. 管理储备 …

我使用阿里云做直播,有什么手段保护直播安全?

摘要&#xff1a; 准备工作 开通阿里云直播服务&#xff1a;阿里云直播服务接收直播流&#xff0c;并提供直播播放地址&#xff0c;完成一场直播需要先开通阿里云直播服务&#xff0c;在 直播官网详情页 中单击 立即开通 &#xff0c;开通阿里云直播服务。 如您已经能够使用阿里…

Activiti6 use spring-boot-starter-web meet requestMappingHandlerMapping error

解决方案&#xff1a; SpringBootApplication(exclude SecurityAutoConfiguration.class)参考链接&#xff1a;https://hub.alfresco.com/t5/alfresco-process-services/activiti6-use-spring-boot-starter-web-meet/m-p/125303