@ 代码随想录算法训练营第9周(C语言)|Day63(单调栈)
Day63、单调栈(包含题目 ● 503.下一个更大元素II ● 42. 接雨水 )
503.下一个更大元素II
题目描述
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
题目解答
c
int* nextGreaterElements(int* nums, int numsSize, int* returnSize) {
int nums1[2*numsSize];
int* res=(int*)malloc(sizeof(int)*numsSize*2);
int rescount=0;
memset(res,-1,sizeof(int)*numsSize*2);
for(int i=0;i<numsSize;i++){
nums1[i]=nums[i];
nums1[i+numsSize]=nums[i];
}
int stack[10001];
int stacktop=0;
stack[stacktop++]=0;
for(int i=1;i<2*numsSize;i++){
if(nums1[i]>nums1[stack[stacktop-1]]){
while(stacktop!=0&&nums1[i]>nums1[stack[stacktop-1]]){
res[stack[stacktop-1]]=nums1[i];
stacktop--;
}
}
stack[stacktop++]=i;
}
*returnSize=numsSize;
return res;
}
题目总结
循环就是首尾相接再加一段,一定注意res的空间是2*size。
42. 接雨水
题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
题目解答
c
int trap(int* height, int heightSize) {
int maxleft[heightSize];
int maxright[heightSize];
maxleft[0]=height[0];
for(int i=1;i<heightSize;i++){
maxleft[i]=fmax(height[i],maxleft[i-1]);
}
maxright[heightSize-1]=height[heightSize-1];
for(int i=heightSize-2;i>=0;i--){
maxright[i]=fmax(height[i],maxright[i+1]);
}
int sum=0;
for(int i=1;i<heightSize-1;i++){
int count=fmin(maxleft[i],maxright[i])-height[i];
if(count>0){
sum+=count;
}
}
return sum;
}
//单调栈
int trap(int* height, int heightSize) {
int stack[heightSize];
int stacktop=0;
stack[stacktop++]=0;
int res=0;
for(int i=1;i<heightSize;i++){
if(height[i]>height[stack[stacktop-1]]){
while(stacktop!=0&&height[i]>height[stack[stacktop-1]]){
int mid=height[stack[stacktop-1]];
stacktop--;
if(stacktop!=0){
int left=height[stack[stacktop-1]];
res+=(fmin(left,height[i])-mid)*(i-(stack[stacktop-1])-1);
}
}
}
stack[stacktop++]=i;
}
return res;
}
题目总结
使用的是双指针来做,分别找到i高度两边比其最高的元素,进行高度计算。