今天晚上是刷题的第二弹,继续单调栈,而且有最经典的接雨水的问题,开冲,马上既可以结束了。
今日任务:
- 503.下一个更大元素II
- 42.接雨水
题目一:503.下一个更大元素II
Leetcode题目:【503.下一个更大元素II】
这个题目需要讲究的是循环数组,那可以把两个数组拼起来,但是如何拼起来如何操作:
1.1 方法一:采用数组拼接的方式处理循环数组
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
stack<int> st;
st.push(0);
vector<int> nums1(nums.begin(), nums.end());
nums.insert(nums.end(), nums1.begin(), nums1.end());
vector<int> result(nums.size(), -1);
for(int i = 1; i<nums.size(); i++){
if(nums[i] <= nums[st.top()]) st.push(i);
else{
while(!st.empty() && nums[i] > nums[st.top()]){
result[st.top()] = nums[i];
st.pop();
}
st.push(i);
}
}
result.resize(nums.size()/2);
return result;
}
};
1.2 方法二:原数组直接模拟(通用方法)
只要是成环的问题,其实可以采用取模的方式来模拟成环的遍历。
就是按照单调栈的模板,把i替换成i%nums.size();
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
stack<int> st;
vector<int> result(nums.size(),-1);
st.push(0);
for(int i = 1; i<nums.size() *2; i++){
if(nums[i % nums.size()] <= nums[st.top()]){
st.push(i % nums.size());
}else{
while(!st.empty() && nums[i % nums.size()] > nums[st.top()]){
result[st.top()] = nums[i % nums.size()];
st.pop();
}
st.push(i % nums.size());
}
}
return result;
}
};
题目二:42.接雨水
Leetcode题目:【42.接雨水】
接雨水这道题目是 面试中特别高频的一道题,也是单调栈 应用的题目,大家好好做做。建议是掌握 双指针 和单调栈,因为在面试中 写出单调栈可能 有点难度,但双指针思路更直接一些。在时间紧张的情况有,能写出双指针法也是不错的,然后可以和面试官在慢慢讨论如何优化。
本体主要采用单调栈来解决这个问题。
左右元素与本元素大的:单调递增栈;
左右元素与本元素小的:单调递减栈;
这个题与之前不同的题目,不仅要去求右边,还要求左边大于他的第一个元素,这样才能形成一个凹槽。如何求左边,其实左边的元素已经在栈里面了,底找到了,左边的柱子找到了,右边的柱子找到了,这样就可以把装的水的体积计算出来了。
其实此题的思路关键就是:
(1)左侧的如何求:左侧的最近的大于本元素的已经是在栈里面了;
(2)面积如何计算:因为左侧的是在栈中,所以需要先弹出元素来
mid = st.top();
st.pop();
h = min(h[st.top()], h[i]) - mid;
w = i - st.top() -1;
其他的基本跟单调栈的模板没有区别。
class Solution {
public:
int trap(vector<int>& height) {
stack<int> st;
st.push(0);
int sum = 0;
for(int i = 1; i<height.size(); i++){
if(height[i] <= height[st.top()]) st.push(i);
else{
while(!st.empty() && height[i]>height[st.top()]){
int mid = st.top();
st.pop();
if(!st.empty()){
int h = min(height[i], height[st.top()]) - height[mid];
int w = i - st.top() - 1;
sum += h*w;
}
}
st.push(i);
}
}
return sum;
}
};