503.下一个更大元素II
class Solution {
public:
/*
关于单调栈的讲解739. 每日温度中已经详细讲解了。
本题基本思路和上面是一样的,只是改为了循环数组
处理循环数组:
不扩充nums,而是在遍历的过程中模拟走了两边nums。
*/
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> result(nums.size(), -1);
if (nums.size() == 0) return result;
stack<int> st;
st.push(0);
for (int i = 1; i < nums.size() * 2; i++) {
// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
if (nums[i % nums.size()] < nums[st.top()]) st.push(i % nums.size());
else 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. 接雨水
双指针法:
class Solution {
public:
/*
双指针方法:
分别定义左右两边最高高度的数组。
每一列雨水的高度,取决于,该列 左侧最高的柱子 和 右侧最高的柱子 二者中最矮的那个柱子的高度。
*/
int trap(vector<int>& height) {
if (height.size() <= 2) return 0;
//记录每列左右两边最高柱子高度的数组
vector<int> maxLeft(height.size(), 0);
vector<int> maxRight(height.size(), 0);
int size = maxRight.size();
// 记录每个柱子左边柱子最大高度
maxLeft[0] = height[0];//初始化为最左边柱子高度
for (int i = 1; i < size; i++) {
maxLeft[i] = max(height[i], maxLeft[i - 1]);//暗含动规思想
}
// 记录每个柱子右边柱子最大高度
maxRight[size - 1] = height[size - 1];
for (int i = size - 2; i >= 0; i--) {
maxRight[i] = max(height[i], maxRight[i + 1]);
}
// 求和
int sum = 0;
for (int i = 0; i < size; i++) {
int count = min(maxLeft[i], maxRight[i]) - height[i];
if (count > 0) sum += count;
}
return sum;
}
};
单调栈法
class Solution {
public:
/*
首先单调栈是按照行方向来计算雨水
从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
*/
int trap(vector<int>& height) {
if (height.size() <= 2) return 0; // 可以不加
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);
} if (height[i] == height[st.top()]) { // 情况二
st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。
st.push(i);
} else { // 情况三
while (!st.empty() && height[i] > height[st.top()]) { // 注意这里是while
int mid = st.top();
st.pop();
if (!st.empty()) {
int h = min(height[st.top()], height[i]) - height[mid];
int w = i - st.top() - 1; // 注意减一,只求中间宽度
sum += h * w;
}
}
st.push(i);
}
}
return sum;
}
};