[代码随想录一刷] 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;代码随想录 文章被收录于专栏

刷题记录~~~

全部评论

相关推荐

04-08 16:35
门头沟学院 Java
站队站对牛:实在是恶心的公司
点赞 评论 收藏
分享
Kurumis:整个简历看下来就发现你其实对测试理解还很浅,很多地方都是硬凑上去,项目也是学生课设级别,没什么含金量 首先是学习建议: 1.系统性了解一个真实工程的框架,有利于你后续提升项目含金量,理解测试的逻辑 2.真正去学一下自动化测试和性能测试 再就是简历本身包装问题: 1.投测试的话就不要说自己独立开发自己测,专注描述自己怎么做测试的 2.项目经历太像套话,很容易让人怀疑你到底真的做过没有,比如并发是具体做了多少并发?自动化脚本是怎么跑兼容性和性能测试的?测试用例写了多少条? 3.教务管理系统一听就是数据库课设作业,含金量不高,不过你可以在原项目基础上重构扩展,比如添加docker容器部署MySQL和Redis,添加消息队列和锁机制防止系统扛不住高并发访问,让它真的像个实际工程 4.技能里性能专项测试没有把握不要乱写,就写你会什么工具就行了,做专项性能测试的都是行业大佬,你要写的话一定要有对应的专项性能测试项目 5.可以在简历里附上项目链接,压缩简历内容的同时提升简历真实性
今天你投了哪些公司?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务