牛客 BM94 接雨水问题 【中等 双指针】

题目

在这里插入图片描述

思路

        答案和讨论请看这里:https://www.lintcode.com/problem/363/note/236598
        或者直接看我的答案想思路


        思路1:两种做法,单调栈和左右求最值,都不是很好想,要多练习
        题型:双指针
        观察题目:可知,基本常识:一个水桶能装多少水,取决于它的短板。
        对于该题,某个位置的水能不能被累加,取决于左右两边最高的档板的位置。
        因此:我们需要记录左右两边最高档板的高度。

        思考2:
        edge case的预先处理:如果heights == null 或者 heights.length < 2 存不住水,
        直接返回0即可。

        每一次 要么左指针右移,要么右指针左移,一定要移动一个。如果两个都不移动,循环出不去,
        就是死循环。如果两个都移动,有可能会出现越界或者重复处理导致结果错误的情况发生。那么,
        每一次该移动哪一个指针呢?
        哪边的墙低,移动哪边。这样比较方便计算当前能够储存的水量。

参考代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * max water
     * @param arr int整型一维数组 the array
     * @return long长整型
     */
    public long maxWater (int[] arr) {
        /*
           答案和讨论请看这里:https://www.lintcode.com/problem/363/note/236598
           或者直接看我的答案想思路


           思路1:两种做法,单调栈和左右求最值,都不是很好想,要多练习
           题型:双指针
           观察题目:可知,基本常识:一个水桶能装多少水,取决于它的短板。
           对于该题,某个位置的水能不能被累加,取决于左右两边最高的档板的位置。
           因此:我们需要记录左右两边最高档板的高度。

           思考2:
           edge case的预先处理:如果heights == null 或者 heights.length < 2 存不住水,直接返回0即可。

           每一次 要么左指针右移,要么右指针左移,一定要移动一个。如果两个都不移动,循环出不去,就是死循环。如果两个都移动,有可能会出现越界或者重复处理导致结果错误的情况发生。那么,每一次该移动哪一个指针呢?
           哪边的墙低,移动哪边。这样比较方便计算当前能够储存的水量。
            */
        if (arr == null || arr.length < 2) return 0;
        int n = arr.length;
        int L = 1, R = n - 2, leftMax = arr[0], rightMax = arr[n - 1];
        int water = 0;

        while (L <= R) {
            if (leftMax <= rightMax) {
                water += Math.max(0, leftMax - arr[L]);
                leftMax = Math.max(leftMax, arr[L++]);
            } else {
                water += Math.max(0, rightMax - arr[R]);
                rightMax = Math.max(rightMax, arr[R--]);
            }
        }
        return water;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值