一、下一个更大元素
题目一:503. 下一个更大元素 II
给定一个循环数组 nums
( nums[nums.length - 1]
的下一个元素是 nums[0]
),返回 nums
中每个元素的 下一个更大元素 。
数字 x
的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1
。
当遍历数组时,如果当前元素大于栈顶索引对应的元素,那么找到了栈顶索引对应元素的“下一个更大元素”,可以持续这样做直到栈为空或者当前元素不再大于栈顶索引对应的元素为止。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> res(n, -1);
stack<int> s;
for (int i = 0; i < n * 2; i++) {
int num = nums[i % n];
while (!s.empty() && nums[s.top()] < num) {
res[s.top()] = num;
s.pop();
}
if (i < n) s.push(i);
}
return res;
}
};
二、接雨水
题目一:42. 接雨水
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
在这个问题中,可以采用单调栈的数据结构,单调栈可以找出右侧第一个比自己大的元素,也可以找出左侧第一个比自己大的元素。这里是建立单调递减的栈,每当遇到一个新的柱子,如果它比堆栈顶的元素小,就把新柱子的索引入栈,如果它跟堆栈顶的元素相等,就替换掉当前堆栈顶的元素。
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0, current = 0;
stack<int> st;
while (current < height.size())
{
while (!st.empty() && height[current] > height[st.top()])
{
int top = st.top();
st.pop();
if (st.empty())
break;
int distance = current - st.top() - 1;
int bounded_height = min(height[current], height[st.top()]) - height[top];
ans += distance * bounded_height;
}
st.push(current++);
}
return ans;
}
};