LeetCode经典面试150题-day6(接雨水)

每日箴言:

一支笔,一包烟,一个hard坐一天 ......

1、题目

今天整一道困难水平的题目 !!!

2、分析

⑴ 、初始化左指针 left 和右指针 right 分别指向数组的两端

⑵ 、初始化左边最大值 leftMax 和右边最大值 rightMax,初始值为数组左端元素和右端元素的高度

⑶ 、初始化雨水容量 water 为 0

⑷ 、当 left <= right 时,执行以下步骤:

        如果 height[left] <= height[right],表示左边高度较小,则比较 height[left] 和 leftMax 的大小:

                如果 height[left] < leftMax,说明左边可以接住雨水,雨水高度为 leftMax - height[left],

                将其累加到 water 中

                 更新 leftMax 为 left 位置的高度

                向右移动左指针,即 left++

        如果 height[left] > height[right],表示右边高度较小,则比较 height[right] 和 rightMax 的大小:

        如果 height[right] < rightMax,说明右边可以接住雨水,雨水高度为 rightMax - height[right],将其累加到 water 中

       更新 rightMax 为 right 位置的高度

       向左移动右指针,即 right--

        如果 height[left] == height[right],表示左右高度相等,可以选择任意一边移动。在这里选择向左移动右指针,即 right--

⑸ 、返回计算得到的雨水容量 water

3、解题

    /**
     * 接雨水
     * <p>
     * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
     * <p>
     * 首先,要形成凹槽才能接到雨水,凹槽的特征就是中间小,两边大 ,这是一个特点
     * 其次,观察图发现,凹槽形成还有一个特征,就是数组会经历一个先递减,再递增的过程,递增到最高处再递减,如果反复形成凹槽
     * 这是一个分析的点,这道题你可以横着来做,也可以竖着来做
     * 
     * 下面是一种解法
     *
     *
     * @param height
     * @return
     */
    public static int trap(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        int water = 0;
        while (left <= right) {
            if (height[left] <= height[right]) {
                if (height[left] < leftMax) {
                    water += leftMax - height[left];
                }
                leftMax = Math.max(leftMax, height[left]);
                left++;
            } else {
                if (height[right] < rightMax) {
                    water += rightMax - height[right];
                }
                rightMax = Math.max(rightMax, height[right]);
                right--;
            }
        }
        return water;
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值