代码随想录Day63 |503.下一个更大元素II 42. 接雨水
503.下一个更大元素II
文档讲解:代码随想录
视频讲解: 单调栈,成环了可怎么办?LeetCode:503.下一个更大元素II
状态
单调栈中存储的元素和单调性都和之前一样
主要是对循环数组怎么处理
//循环数组的处理方法
//循环数组相当于是需要遍历两次原本的数组
//1. 可以再复制一个数组在原本的数组后面
//2. 将遍历的循环长度增加为2*n-1,然后对i取mod(n)那么超过n的i也会变为i
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int len = nums.size();
vector<int> res(len,-1);
if(len == 0) return res;
stack<int> check;
check.push(0);
for(int i = 1;i<2*len-1;i++)
{
while(!check.empty() && nums[i%len] > nums[check.top()])
{
res[check.top()] = nums[i%len];
check.pop();
}
check.push(i%len);
}
return res;
}
};
42.接雨水
文档讲解:代码随想录
视频讲解: 单调栈,经典来袭!LeetCode:42.接雨水
状态
双指针
两个指针分别从头和尾向中间移动,并记录扫描过的左端和右端木板最大值。
当右端木板最大值比左端木板最大值大时,我们考虑左指针指向的当前木板。那么其一定是可以存水的,因为其右边有比他高的木板。具体存水量是当前的左端最大值减去当前木板高度。
//双指针
class Solution {
public:
int trap(vector<int>& height) {
int left = 0;
int right = height.size()-1;
int res = 0;
int leftmax = height[left];
int rightmax = height[right];
while(left <= right)
{
leftmax = max(leftmax,height[left]);
rightmax = max(rightmax,height[right]);
//当左边的最高小于右边最高
//可以以左边木板的高度来确定盛水量,因为右边始终有一个比他高的为他兜底
//有点贪心的想法
//盛水量就是左边的最大值减去当前木板的高度。
if(leftmax<rightmax)
{
res += leftmax-height[left];
left++;
}
else
{
res += rightmax-height[right];
right--;
}
}
return res;
}
};
单调栈
对于一个下标i寻找其左边的第一个大值和右边第一个大值,这个位置的积水量就可以求得
对于栈内一个可以积水的情况,栈头元素表示当前木板,栈头第二个元素应当表示当前木板的左边最大值,待入栈元素表示当前木板的右边木板。所以在该单调栈中应该是栈头元素较小,栈底元素较大。
当遇到与栈头相同的元素要入栈时,应当弹出栈头,压入最新的下标。
栈中存放的元素:当前木板的下标。
class Solution {
public:
int trap(vector<int>& height) {
int res = 0;
stack<int> check;
check.push(0);
for(int i = 1;i<height.size();i++)
{
//如果待压入元素比栈头元素小直接压入
if(height[i] < height[check.top()])
{
check.push(i);
}
//如果相等,先弹出再压入
else if(height[i] == height[check.top()])
{
check.pop();
check.push(i);
}
//如果大,那说明可以计算积水量
else
{
while(!check.empty() && height[i] > height[check.top()])
{
//当前积水的木板
int mid = check.top();
check.pop();
if(!check.empty())
{
//计算积水高度,应当是栈头第二个元素和待压入元素的最小值
int h = min(height[check.top()],height[i]) - height[mid];
//计算积水宽度
int w = i-check.top()-1;
res += h*w;
}
}
//压入
check.push(i);
}
}
return res;
}
};