题解 | 接雨水问题

接雨水问题

https://www.nowcoder.com/practice/31c1aed01b394f0b8b7734de0324e00f

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * max water
     * @param arr int整型vector the array
     * @return long长整型
     */
    //单调栈,空间复杂度为On
    /*long long maxWater(vector<int>& arr) {
        // write code here
        stack<int> st;//存下标,单调递减栈
        long long water=0;
        int n=arr.size();
        if(n<3)
        {
            return 0;
        }
        for(int i=0;i<n;i++)
        {
            while(!st.empty()&&arr[i]>arr[st.top()])//当栈中存在元素并且当前元素大于栈顶元素,所以说明此时有一个凹槽
            {
                //栈顶元素为坑底,弹出以后如果有栈顶则新的栈顶元素为左边界,当前元素为右边界;否则直接跳出
                int bottom=st.top();
                st.pop();
                if(st.empty())
                {
                    break;
                }
                int left=st.top();
                int minheight=min(arr[left],arr[i]);
                water+=((minheight-arr[bottom])*(i-left-1));
            }
            st.push(i);
        }
        return water;

    }*/
    //双指针,空间复杂度为O1
    //双指针的思路是左右两个指针往中间偏移,记录左指针左边最大的数组值和右指针右边最大的数组值
    //当遇到凹槽时当前指针的leftmax和rightmax都大于当前指针的数组值,此时只需计算当前数组值能装多少雨水
    //想象一下,左右两边都比该数组值高,所以当前数组值能存的雨水一定不会漏出,依次类推,统计每个比左右边界小的数组值
    //能装雨水,累加即可。
     long long maxWater(vector<int>& arr) {
        // write code here
        long long water=0;
        int n=arr.size();
        if(n<3)
        {
            return 0;
        }
        int left=0;
        int right=n-1;
        int leftmax=0;//left左边的最大值
        int rightmax=0;//right右边的最大值
        while(left<=right)//left可能和right在同一位置,例如遇到左边最高值,left是指向下一个,而right是指向右边最高值的上一个
        {
            if(leftmax<=rightmax)//左边界小,要以左边界为高计算雨水
            {
                if(arr[left]>leftmax)
                {
                    leftmax=arr[left];//更新左边界,确保左边界一定比当前数组值大,如果小,则不计算雨水
                }
                else 
                {
                    water+=(leftmax-arr[left]);//相当于只接当前位置所能装的雨水,即左边界与当前位置数组值的差值
                }
                left++;//右移,也能保证当前位置所装雨水值不会被累加计算
            }
            else //右边界小,要以右边界为高计算雨水
            {
              if(arr[right]>rightmax)
                {
                    rightmax=arr[right];//更新右边界,确保右边界一定比当前数组值大,如果小,则不计算雨水
                }
                else 
                {
                    water+=(rightmax-arr[right]);//相当于只接当前位置所能装的雨水,即右边界与当前位置数组值的差值
                }
                right--;//左移,也能保证当前位置所装雨水值不会被累加计算
            }
        }
       
        return water;

    }

};

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4444次浏览 78人参与
# 找AI工作可以去哪些公司? #
9919次浏览 298人参与
# 米连集团26产品管培生项目 #
13470次浏览 285人参与
# 你的实习产出是真实的还是包装的? #
20705次浏览 346人参与
# 从事AI岗需要掌握哪些技术栈? #
9681次浏览 373人参与
# 春招至今,你的战绩如何? #
67431次浏览 598人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
15642次浏览 226人参与
# AI面会问哪些问题? #
28959次浏览 616人参与
# 中国电信笔试 #
32269次浏览 295人参与
# 你做过最难的笔试是哪家公司 #
35535次浏览 297人参与
# 金三银四,你的春招进行到哪个阶段了? #
22529次浏览 284人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
341184次浏览 2175人参与
# 如何准备秋招 #
78321次浏览 868人参与
# 同bg的你秋招战况如何? #
212264次浏览 1121人参与
# 哪些公司真双非友好? #
69797次浏览 289人参与
# 应届生被毁约被毁意向了怎么办 #
63346次浏览 305人参与
# 阿里笔试 #
179346次浏览 1323人参与
# 机械人避雷的岗位/公司 #
62723次浏览 393人参与
# 小马智行求职进展汇总 #
25150次浏览 80人参与
# 第一份工作一定要去大厂吗 #
15135次浏览 123人参与
# 担心入职之后被发现很菜怎么办 #
291423次浏览 1210人参与
# 为了减少AI幻觉,你注入过哪些设定? #
26316次浏览 310人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务