leetcode第42题,接雨水,java实现

15 篇文章 0 订阅

题目链接

运行结果

执行结果:通过
执行用时 :2 ms, 在所有 Java 提交中击败了50.62%的用户
内存消耗 :37.5 MB, 在所有 Java 提交中击败了83.13%的用户

代码与注释

class Solution {
    public int trap(int[] height) {
        int left = 1; // 左指针
        int right = height.length-2; // 右指针
        int left_max = 0; // 记录左最高
        int rigth_max = 0; // 记录右最高
        int sum = 0;
        
        while (left <= right)
        {
            // 如果考察的列的左边列比右边的列小
            if (height[left-1] < height[right+1])
            {
                left_max = Math.max(left_max, height[left-1]);
                if (left_max > height[left]) sum += left_max - height[left];              
                left++;
            }
            // 如果考察的列左边的列大于等于右边的列
            else 
            {
                rigth_max = Math.max(rigth_max, height[right+1]);
                if (rigth_max > height[right]) sum += rigth_max - height[right];
                right--;
            }
           
        }
        return sum;
    }
}

做题体会

  1. 用双指针法,较矮的向较高的移动,只遍历一次,将代码的复杂度降低到O(n),n为数组长度。
  2. 主要思想是考察每一列能盛多少雨水,总的雨水数是每列雨水的总和。
  3. 每列能盛多少雨水的关键在于,当前列的高度是否比左右最高列的矮的那个还要矮,如果是的话,那么盛的雨水就等于左右最高列的矮的那个减去当前列的高度,否则当前列不能盛雨水。
  4. 如何知道左右最高的列中矮的那一个呢?传统思路是直接比较两个列的高度,这里的思路比较巧妙,通过判断height[left-1] < height[right+1]来间接的得到,left_max一定是小于right_max的,因为left_max取自height[left-1],而right_max取自height[right+1]。
  5. 不关心左右最高的具体位置,只关心其具体高度,左右最高在遍历过程中不断被更新,从左往右遍历,关心历史左最高,因为历史左最高,一定小于历史右最高。从右往左遍历,关心历史右最高,因为历史右最高一定小于历史左最高,通过比较条件,把当前列需要跟两个最高比较的情况,简化成了跟两者中最矮的比较。
  6. 当前列的上一个历史状态,谁矮就在谁的方向上推进,考察谁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值