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

四川手机网站设计方案市场监督管理局官网

四川手机网站设计方案,市场监督管理局官网,优秀企业网站建设定制,国外做地铁设计的公司网站目录 一,每日温度 二,下一个更大的元素I 三,下一个更大的元素II 四,接雨水 小结: 单调栈是一种特殊的栈结构,里面的元素按照单调递增或者递减的顺序排列。常用于解决元素左边或者右边比它大或者小的问…

目录

一,每日温度

二,下一个更大的元素I

三,下一个更大的元素II

四,接雨水

小结:


 单调栈是一种特殊的栈结构,里面的元素按照单调递增或者递减的顺序排列。常用于解决元素左边或者右边比它大或者小的问题。

一,每日温度

题目链接:739. 每日温度 - 力扣(LeetCode)

【题目描述】

 对于给定的一个temperatures数组,每个元素表示当天的温度。对于每天的温度,求出下一次更高的温度出现在几天后。

【算法】单调栈

我们可以维护一个栈结构,先将数组的首元素入栈,然后开始遍历这个数组,如果遍历到的数组元素比栈顶元素小,那么就入栈;如果相等,也入栈;当遍历到的数组元素比此时栈顶的元素大时,记录此时相隔的天数,然后将栈顶元素弹出,继续比较栈顶的元素和数组元素的大小,直到栈顶元素小于或者等于栈顶元素,此时将该数组元素入栈。然后接着遍历下一个数组元素,依次循环。

由于题目中求的是相隔的天数,所以我们不需要将数组元素入栈,只需入栈该元素的下标即可,这样就可以直接计算相隔的天数:数组元素对应的下标减去栈顶元素对应的下标,就是该栈顶元素与下一个更高温度相隔的天数。 

图示:(以题目中的示例1为例)

可以发现,栈中的元素(下标对应的元素)始终保持单调递减(从栈底到栈顶),因此成为单调栈。 

【代码】

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {int n=temperatures.size();vector<int> ans(n,0);stack<int> st;//存储下标st.push(0);for(int i=1;i<n;i++){//遇到温度大于栈顶的,就一直出栈,保持递减性while(!st.empty()&&temperatures[st.top()]<temperatures[i]){int index=st.top();st.pop();ans[index]=i-index;}st.push(i);}return ans;}
};

时间复杂度O(N),每个元素最多入栈依次。空间复杂度O(N) 

二,下一个更大的元素I

题目链接:496. 下一个更大元素 I - 力扣(LeetCode)

【题目描述】

本题存在两个数组,nums1是nums2的子集,对于nums1数组的每个元素,求出这些元素在对应nums2数组中的下一个更大的元素。如果不存在,则为-1

【算法】单调栈

本题与上一题的思路一样,只不过加了一点要求。

求当前元素的下一个更大的元素,就需要维护一个单调栈(单调递减)。

本题还是求数组nums2上每个元素的下一个更大的元素是多少。所以还是在nums2数组上使用单调栈。和上题的过程一样,只不过在判断的时候,还需加上一个条件。

假设找到了当前栈顶的下一个更大元素k,还需判断栈顶元素是否在nums1中出现过,如果该元素在nums1中出现过,那么就将k记录在最终结果数组ans中,不过还需要保证和nums1数组的位置一一对应。

所以可以做下预处理工作,将数组nums1中的元素和下标使用哈希表保存起来。

初始化ans数组时,可以全部初始化为-1.

【代码】

class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {int n=nums1.size();vector<int> ans(n,-1);unordered_map<int,int> hash;for(int i=0;i<n;i++)hash[nums1[i]]=i;stack<int> st;//单调递减st.push(0);for(int i=1;i<nums2.size();i++){while(!st.empty()&&nums2[st.top()]<nums2[i]){//判断是否在nums1中出现过if(hash.count(nums2[st.top()])>0){//求出该元素在nums1中对应的下标int index=hash[nums2[st.top()]];//记录结果ans[index]=nums2[i];}st.pop();}st.push(i);}return ans;}
};

三,下一个更大的元素II

题目链接:503. 下一个更大元素 II - 力扣(LeetCode)

【题目描述】

 求一个数组nums每一个元素的下一个更大的数,该数组是循环数组,数组最后一个元素接下来的元素就是数组的第一个元素。

【算法】单调栈

求下一个更大的元素,单调栈(单调递减栈)。

大致的方向还是使用单调栈。本题的重点是:如何处理循环数组。

方法一:是将原数组nums在后面再拼接一份。然后使用单调栈求下一个更大的元素。

将两个nums数组拼接起来,使用单调栈求出每一个元素的下一个更大值,存储在ans数组中,然后将ans数组的大小减为一半。

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {//拼接两个数组vector<int> nums1(nums.begin(),nums.end());nums.insert(nums.begin(),nums1.begin(),nums1.end());vector<int> ans(nums.size(),-1);stack<int> st;//单调递减st.push(0);for(int i=1;i<nums.size();i++){while(!st.empty()&&nums[st.top()]<nums[i]){ans[st.top()]=nums[i];st.pop();}st.push(i);}//将数组减为原来的一般ans.resize(nums.size()/2);return ans;}
};

方法二:也可以不用扩充数组,在遍历的时候模拟走两边nums即可。

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {int n=nums.size();vector<int> ans(n,-1);stack<int> st;//单调递减st.push(0);//模拟走两边nums//当遍历完最后一个元素,执行++后,再取模n,会回到数组的开始for(int i=1;i<2*n;i++){while(!st.empty()&&nums[st.top()]<nums[i%n]){ans[st.top()]=nums[i%n];st.pop();}st.push(i%n);}return ans;}
};

四,接雨水

题目链接:42. 接雨水 - 力扣(LeetCode)

【解法一】双指针 

求这些柱子中一共有多少雨水。看每个柱子可以"接"多少雨水。

也就是统计每个柱子上有多少水,然后将每个柱子上的水加起来即可。

问题是如何求每个柱子上有多少水?

对于第i个柱子,求第i个柱子上有多少水,需要求出第i个柱子左边柱子最高的高度,以及第i个柱子右边柱子最高的高度,取两者的最小值,然后再减去当前柱子的高度。

【代码】

class Solution {
public:int trap(vector<int>& height) {//双指针int n=height.size();vector<int> maxLeft(n,0);auto maxRight=maxLeft;//记录左边最大值maxLeft[0]=height[0];for(int i=1;i<n;i++)maxLeft[i]=max(maxLeft[i-1],height[i]);//记录右边最大值maxRight[n-1]=height[n-1];for(int i=n-2;i>=0;i--)maxRight[i]=max(maxRight[i+1],height[i]);int ans=0;for(int i=0;i<n;i++){int count=min(maxLeft[i],maxRight[i])-height[i];if(count>0) ans+=count;}return ans;}
};

【解法二】单调队列

这种思路是求柱子与柱子之间的雨水量。

首先需要明白,当后一个柱子高度大于前一个柱子高度,那么一定是会有雨水的。

所以我们需要求下一个更大的元素,使用单调递减栈。

思路,与前面题的思路一致。


当遍历到的元素大于栈顶元素时:

此时的栈顶就是下图的中间柱子,下标记为mid,对应的高度为height[mid],将栈顶元素弹出。

此时的栈顶元素st.top(),就是最左边的柱子,对应的高度为height[st.top()]。

此时遍历到的元素是最右边的柱子,下标为i,柱子高度为height[i]。

最后只需计算出中间雨水的长和宽然后相乘即可。

h=min(height[st.top()],height[i])-height[mid]

w=i-st.top()-1

【代码】

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int ans=0;stack<int> st;//单调递减st.push(0);for(int i=1;i<n;i++){while(!st.empty()&&height[st.top()]<height[i]){int mid=st.top();st.pop();if(!st.empty()){int h=min(height[st.top()],height[i])-height[mid];int w=i-st.top()-1;ans+=h*w;}}st.push(i);}return ans;}
};

小结:

单调栈常用于解决元素左侧或者右侧第一个更大后者更小的问题。

核心原理:

  • 单调递增栈:栈内元素从栈底到栈顶递增,用于寻找更小的元素。

  • 单调递减栈:栈内元素从栈底到栈顶递减,用于寻找更大的元素。

  • 遍历数组时,若当前元素破坏单调性,则弹出栈顶元素,直到满足单调性。

http://www.dtcms.com/wzjs/322958.html

相关文章:

  • 网站开发私活哈尔滨百度搜索排名优化
  • 淄博周村学校网站建设公司南阳seo
  • 购物网站建设过程免费的网站域名查询565wcc
  • 海南网站运营托管咨询网络推广员岗位职责
  • 热点新闻事件及观点最新seo自动优化软件
  • winserverfrp可以做网站吗网络推广员一个月多少钱
  • wordpress站点切换为中文北京网站优化快速排名
  • 做竞价网站访问突然变少重庆seo公司
  • 比较好的公司网站郑州网络推广平台有哪些
  • java可以做网站郑州网站建设
  • 北京哪家公司做网站程序员培训机构排名前十
  • 深圳建设网站排名电脑清理优化大师
  • reeyee网站建设西安seo排名
  • 德州网站建设维护潍坊网站建设公司
  • 沙河企业做网站营销软文300字范文
  • 网络大型游戏排行长沙seo网站
  • 如何用wordpress搭建网站软文广告经典案例600
  • 营销型网站网站设计网络推广公司排行榜
  • 大学教学应用网站开发现状友情链接交换网站
  • 深圳市住房和建设局门户网站谷歌推广app
  • 改进网站建设google应用商店
  • 网站做数据分析百度小说搜索热度排行榜
  • 宁波专业网站建设新闻近期大事件
  • 采用什么方法推广网站网站域名怎么注册
  • wordpress 实现 wiki海阳seo排名优化培训
  • 发明迷网站豆渣做豆腐广告网站建设网站排名优化
  • 新农村建设专题网站哪里能搜索引擎优化
  • 昭通市住房和城乡建设局网站自助建站平台
  • 专门做日本旅游的网站有哪些南昌seo外包公司
  • 企业网站建设推荐兴田德润软件开发工资一般多少