算法刷题记录 Day51

算法刷题记录 Day51

Date: 2024.04.19

lc 42. 接雨水

// 单调栈
class Solution {
public:
    int trap(vector<int>& height) {
        // 思路2:单调栈。当有个元素要入栈时。若该元素小于等于栈顶,则直接入栈;
        // 若该元素大于栈顶,则出栈。出栈后的新的栈顶,就是该出栈元素的左侧最大值。
        // (当前索引-新栈顶索引-1) * (min(左,右)-当前), 即为累计的雨水;
        // 若出栈后无元素,则该元素自身为最大值,不统计该出栈值接了多少雨水。
        int n = height.size();
        int cur_idx = 0;
        stack<int> st;  // 存放单调栈的索引;

        int sum = 0;
        while(cur_idx < n){
            while(!st.empty() && height[cur_idx] >= height[st.top()]){
                int cur_pop_idx = st.top();
                st.pop();
                if(st.empty()){ //若出栈一个值后栈空,则该值自身为最大值,不累加雨水
                    
                }
                else{
                    // cout<<(min(height[cur_idx], height[st.top()]) - height[cur_pop_idx]) * (cur_idx-st.top()-1))<<endl;
                    // cout<<"当前索引:"<<cur_pop_idx<<endl;
                    // cout<<"前一索引:"<<st.top()<<endl;
                    // cout<<"后一索引:"<<st.top()<<endl;
                    // cout<<"当前累加值:("<<min(height[cur_idx], height[st.top()])<<" - "<<height[cur_pop_idx]<< ") * "<<(cur_idx-st.top()-1)<<endl;
                    sum += (min(height[cur_idx], height[st.top()]) - height[cur_pop_idx]) * (cur_idx-st.top()-1);
                }
            }
            st.push(cur_idx);
            cur_idx++;
        }
        return sum;
    }
};


// 双指针
class Solution {
public:
    int trap(vector<int>& height) {
        // 对于每个柱子(除头尾),能够接水的量是其左侧和右侧最大值中的较小值。
        // 因此,使用双指针,遍历两次数组,获取每个位置的左侧最大值和右侧最大值。
        // 再遍历一次数组,计算每个位置能接的雨水量并累计。
        int n = height.size();
        vector<int> leftHeight(n, 0);
        vector<int> rightHeight(n, 0);

        int left_max = height[0];
        for(int i=1; i<n; i++){
            leftHeight[i] = left_max;
            left_max = max(left_max, height[i]);
        }

        int right_max = height[n-1];
        for(int i=n-2; i>=0; i--){
            rightHeight[i] = right_max;
            right_max = max(right_max, height[i]);
        }

        int sum = 0;
        for(int i=1; i<n-1; i++){
            sum += max(min(leftHeight[i], rightHeight[i]) - height[i], 0);
        }
        return sum;
    }
};

lc 503. 下一个更大元素II

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        // 相当于把两个数组相连后进行处理。
        vector<int> next(nums.size(), -1);
        int cur_idx = 0;
        stack<int> st;

        while(cur_idx < 2*nums.size()){
            int tmp_idx = cur_idx % nums.size();
            while(!st.empty() && nums[tmp_idx] > nums[st.top()]){
                if(next[st.top()] == -1){
                    next[st.top()] = nums[tmp_idx];
                }
                st.pop();
            }
            st.push(tmp_idx);
            cur_idx++;
        }
        return next;
    }
};
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值