503 我的思路是既然是循环数组 那就最多遍历两圈 其他的跟单调栈写法一模一样
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> result(nums.size(), -1);
if (nums.size()==1) return result;
stack<int> stack;
stack.push(0);
int i=1;
while (i<2*nums.size()) {
if (nums[i%nums.size()]<=nums[stack.top()]) {
stack.push(i%nums.size());
}
else {
while (!stack.empty() && nums[i%nums.size()]>nums[stack.top()]) {
result[stack.top()] = nums[i%nums.size()];
stack.pop();
}
stack.push(i%nums.size());
}
i++;
}
return result;
}
};
42难题
单调栈思路是这个图 cr to 代码随想录 按行来计算
按行来要找每个矩阵块的h和w
找到h就要考虑三个height才能计算出凹槽面积 这三个height的取值很巧妙 最右边的是正在遍历到的大于stack.top()的height 中间是正要出栈的 最左边是再左边一个
//单调栈
class Solution {
public:
int trap(vector<int>& height) {
stack<int> stack;
stack.push(0);
int result=0;
for (int i=1; i<height.size(); i++) {
if (height[i]<height[stack.top()]) stack.push(i);
if (height[i]==height[stack.top()]) {
stack.pop();
stack.push(i);
}
else {
while (!stack.empty() && height[i]>height[stack.top()]) {
int mid=stack.top();
stack.pop();
if (!stack.empty()) {
int w=i-stack.top()-1;
int h=min(height[stack.top()], height[i])-height[mid];
result += w*h;
}
}
stack.push(i);
}
}
return result;
}
};
双指针法很容易懂啦 其实我觉得更像动态规划 找每个元素左边最大和右边最大 二者中小的那个减掉自己的height就是这一列的积水量 找左边最大和右边最大的时候用动态规划时间复杂度就是O(n)了
//双指针
class Solution {
public:
int trap(vector<int>& height) {
if (height.size()==1) return 0;
vector<int> lHeight(height.size(), 0);
vector<int> rHeight(height.size(), 0);
lHeight[1]=height[0];
for (int i=2; i<height.size(); i++) {
lHeight[i]= max(lHeight[i-1], height[i-1]);
}
rHeight[height.size()-2]=height[height.size()-1];
for (int i=height.size()-3; i>=0; i--) {
rHeight[i]=max(rHeight[i+1], height[i+1]);
}
int result=0;
for (int i=1; i<height.size()-1; i++) {
if (min(lHeight[i], rHeight[i])-height[i]>0) result+=min(lHeight[i], rHeight[i])-height[i];
}
return result;
}
};