503.下一个更大元素Ⅱ、42.接雨水
503.下一个更大元素Ⅱ
类似于下一个更大元素Ⅰ,对于下一个更大元素Ⅱ,我们可以利用相同的处理方法,即用单调栈的思想,但是要访问的数组是可以循环的,因此,我们访问两遍数组即可。
具体来说,我们可以使用一个栈来维护一个单调递减的序列,栈中存储的是 nums2 数组中的下标。当遍历到一个新的元素时,我们将栈顶元素与当前元素比较,如果栈顶元素小于当前元素,那么栈顶元素的下一个更大元素就是当前元素。我们可以将栈顶元素出栈,并将其下一个更大元素存储到哈希表中。重复这个过程,直到栈为空或者栈顶元素大于等于当前元素。最后,将当前元素的下标入栈。
最后,我们可以遍历 nums1 数组,从哈希表中查找每个元素的下一个更大元素。如果哈希表中存在该元素的下一个更大元素,就将其存储到结果数组中。否则,将 -1 存储到结果数组中。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int>result(nums.size(),-1);
stack<int>st;
for(int ii =0;ii<2*nums.size();ii++)
{
while(!st.empty()&&nums[st.top()]<nums[ii%nums.size()])
{
result[st.top()] = nums[ii%nums.size()];
st.pop();
}
st.push(ii%nums.size());
}
return result;
}
};
42.接雨水
直接解法
可以发现,接雨水的数量取决于两个因素:左边最高的柱子和右边最高的柱子中较矮的那个,以及当前柱子的高度。因此,我们可以遍历一遍数组,分别记录每个位置左边最高的柱子和右边最高的柱子,然后再遍历一遍数组,计算每个位置能接到的雨水的数量。
具体来说,我们可以使用两个数组 left_max 和 right_max 来记录每个位置左边和右边最高的柱子高度。对于每个位置 i,它能接到的雨水的数量就是 min(left_max[i], right_max[i]) - height[i],如果这个值为负数,则说明当前位置不能接到雨水,因此将其置为 0。最后,将所有位置能接到的雨水的数量相加即可得到最终的答案。
代码
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if (n == 0) return 0;
vector<int> left_max(n), right_max(n);
left_max[0] = height[0];
right_max[n - 1] = height[n - 1];
for (int i = 1; i < n; i++) {
left_max[i] = max(left_max[i - 1], height[i]);
}
for (int i = n - 2; i >= 0; i--) {
right_max[i] = max(right_max[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans += max(min(left_max[i], right_max[i]) - height[i], 0);
}
return ans;
}
};
单调栈
我们可以维护一个单调递减的栈,用来存储高度递减的柱子的下标。当遍历到一个新的柱子时,如果当前栈为空,则将该柱子的下标入栈;否则,如果当前柱子的高度小于等于栈顶柱子的高度,则将该柱子的下标入栈;否则,我们可以弹出栈顶元素,计算当前位置能接到的雨水的数量,并将结果累加到答案中,直到当前栈为空或者栈顶柱子的高度大于当前柱子的高度。最后,将当前柱子的下标入栈。
代码
class Solution {
public:
int trap(vector<int>& height) {
stack<int>st;
int result = 0;
st.push(0);
for(int ii =1;ii<height.size();ii++)
{
while(!st.empty()&&height[ii]>height[st.top()])
{
if(st.size()==1)
st.pop();
else
{
int mid = st.top();
st.pop();
int front = st.top();
result+=(min(height[front],height[ii])-height[mid])*(ii-front-1);
}
}
st.push(ii);
}
return result;
}
};