[代码随想录一刷] day59 单调栈

503.下一个更大元素II

一遍过,走两圈%一下遍历,控制入栈只在第一圈即可。

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> res(nums.size(), -1);
        stack<int> st;

        for (int i = 0; i < nums.size() * 2; i++) {
            while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
                res[st.top()] = nums[i % nums.size()];
                st.pop();
            }
            if (i < nums.size()) {
                st.push(i);
            }
        }
        return res;

    }
};

42. 接雨水

注意,如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。

  • 当当前元素大于栈顶时,栈顶就是凹形的底部,栈顶下一个元素就是左边界,最好画图模拟一下比较细节。
class Solution {
public:
    int trap(vector<int>& T) {
        if (T.size() <= 2) return 0;
        stack<int> st;
        st.push(0);
        int sum = 0;
        for (int i = 1; i < T.size(); i++) {
            if (T[st.top()] > T[i]) {
                st.push(i);
            } 
            else if (T[st.top()] == T[i]) {
                st.pop();
                st.push(i);
            } 
            else {
                while (!st.empty() && T[st.top()] < T[i]) {
                    int mid= st.top();
                    st.pop();
                    if (!st.empty()) {
                        int h = min(T[st.top()], T[i]) - T[mid];
                        int w = i - st.top() - 1;
                        sum += h * w;
                    }
                }
                st.push(i);
            }
        }
        return sum;
    }

};

暴力双指针,从列来看,雨水的高度= 两侧最矮的高度-当前位置高度, 用双指针找两边最高的。

alt

//每次都双指针向两边寻找,会超时
class Solution {
public:
    int trap(vector<int>& T) {
        int sum = 0;
        for (int i = 0; i < T.size(); i++) {
            if (i == 0 || i == T.size() - 1) continue;
            int rHeight = T[i];
            int lHeight = T[i];
            for (int r = i + 1; r < T.size(); r++) {
                if (T[r] > rHeight) rHeight = T[r];
            }
            for (int l = i - 1; l >= 0; l--) {
                if (T[l] > lHeight) lHeight = T[l];
            }
            int h = min(lHeight, rHeight) - T[i];
            sum += h;
        }
        return sum;
    }

};
//先记录两边最高的,可以重复利用,用空间换时间,避免超时
class Solution {
public:
    int trap(vector<int>& T) {
        int sum = 0;
        vector<int> maxL(T.size());
        vector<int> maxR(T.size());
        maxL[0] = T[0];
        maxR[T.size() - 1] = T[T.size() - 1];
        for (int i = 1; i < T.size(); i++) {
            maxL[i] = max(T[i], maxL[i - 1]);
        }
        for (int i = T.size() - 2; i >= 0 ; i--) {
            maxR[i] = max(T[i], maxR[i + 1]);
        }
        for (int i = 0; i < T.size(); i++) {
            if (i == 0 || i == T.size() - 1) continue;
            int h = min(maxL[i], maxR[i]) - T[i];
            sum += h;
        }
        return sum;
    }

};
剑指&amp;代码随想录 文章被收录于专栏

刷题记录~~~

全部评论

相关推荐

2024-12-10 00:08
韩山师范学院 Java
讲道理的变色龙在午休:26届已经卷成这个b样了吗,遥想我们24届同学能用java敲个小游戏都算厉害了,20届的更加是一条狗都能找到工作。只能说祝你好运兄弟
点赞 评论 收藏
分享
2024-12-05 18:57
已编辑
吉林大学 Java
张伟要好好学习:这么巧的,我叫安赛龙,祝贺兄弟
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务