503. 下一个更大元素 II

题目链接:503. 下一个更大元素 II

给定一个循环数组 numsnums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素

数字 x下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1

思路与实现

我的想法是,用单调栈遍历两遍数组nums,第一遍遍历的结果保留,第二遍遍历在原来的基础上继续。代码写完通过,如下:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        stack<int> stk;
        vector<int> results(nums.size(), -1);
        for(int i = 0;i<2 * nums.size();i++){
            int curi = i % nums.size();
            while(!stk.empty() && nums[stk.top()] < nums[curi]){
                results[stk.top()] = nums[curi];
                stk.pop();
            }
            stk.push(curi);
        }
        return results;
    }
};

42. 接雨水

题目链接:42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

思路与实现

用两个单调栈来处理这个问题。首先从左向右遍历,记录下每个柱子左边的最长的柱子的长度。再从右向左遍历,记录下每个柱子右边的最长的柱子的长度。当前柱子能够接的雨水等于左右最长柱子的最小值,减去当前柱子的长度。代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> stk1, stk2;
        vector<int> leftMax(height.size(), -1);
        vector<int> rightMax(height.size(), -1);

        for(int i = 0;i<height.size();i++){
            if(stk1.empty()) stk1.push(i);
            else{
                if(height[stk1.top()] > height[i]){
                    leftMax[i] = height[stk1.top()];
                }
                else stk1.push(i);
            }
        }

        for(int i = height.size() - 1;i >= 0;i--){
            if(stk2.empty()) stk2.push(i);
            else{
                if(height[stk2.top()] > height[i]){
                    rightMax[i] = height[stk2.top()];
                }
                else stk2.push(i);
            }
        }

        int result = 0;
        for(int i = 0;i<height.size();i++){
            if(leftMax[i] != -1 && rightMax[i] != -1){
                int minAround = min(leftMax[i], rightMax[i]);
                result += (minAround - height[i]);
            }
        }
        return result;
    }
};

看了一下,我这种其实是双指针写法。单调栈的思路,参考代码随想录,代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size() <= 2) return 0;
        stack<int> stk;
        stk.push(0);
        int result = 0;
        for(int i = 1;i<height.size();i++){
            if(height[i] < height[stk.top()]){
                stk.push(i);
            }
            else if(height[i] == height[stk.top()]){
                stk.pop();
                stk.push(i);
            }
            else{
                while(!stk.empty() && height[i] > height[stk.top()]){
                    int mid = stk.top();
                    stk.pop();
                    if(!stk.empty()){
                        int h = min(height[stk.top()], height[i]) - height[mid];
                        int w = i - stk.top() - 1;
                        result += h * w;
                    }
                }
                stk.push(i);
            }
        }
        return result;
    }
};

上面的代码简化版:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size() <= 2) return 0;
        stack<int> stk;
        stk.push(0);
        int result = 0;
        for(int i = 1;i<height.size();i++){
            while(!stk.empty() && height[i] > height[stk.top()]){
                int mid = stk.top();
                stk.pop();
                if(!stk.empty()){
                    int h = min(height[stk.top()], height[i]) - height[mid];
                    int w = i - stk.top() - 1;
                    result += h * w;
                }
            }
            stk.push(i);
        }
        return result;
    }
};
02-09 14:11