算法题【42. 接雨水】 难度hard 最简单解法

文章介绍了LeetCode中难度为hard的接雨水问题,给出了两种解法:面积法和双指针法。在面积法中,分别计算左右两侧的最大高度并求总面积,然后减去柱子本身的面积和围墙面积得到雨水面积。双指针法中,通过左右两个指针移动,比较左右两侧高度并更新最大值,累加可接雨水量。最终,双指针法在执行效率上更优。
摘要由CSDN通过智能技术生成

一、题目:42. 接雨水

难度:hard

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
42 接雨水

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

二、解法

解法1:面积法

接雨水-面积法

class Solution {
    // 1. 面积法
    public int trap(int[] height) {
        // 左侧
        int leftMax = 0;// 最大值
        int s1 = 0;// 绿色部分面积
        // 右侧
        int rightMax = 0;// 最大值
        int s2 = 0;// 黄色部分面积

        // 计算绿色部分面积
        for (int i = 0; i < height.length; i++) {
            leftMax = Math.max(leftMax, height[i]);
            s1 += leftMax;
        }
        // 计算黄色部分面积
        for (int i = height.length - 1; i >= 0; i--) {
            rightMax = Math.max(rightMax, height[i]);
            s2 += rightMax;
        }
        // 柱子面积 (紫色部分)
        int colArea = Arrays.stream(height).sum();
        // 整体面积 (红细线圈出的长方形)
        int overallArea = leftMax * height.length;
        
        // 雨水面积=s1+s2-整体面积-围墙面积
        return s1 + s2 - overallArea - colArea;
    }
}

解答成功:
执行耗时:3 ms,击败了33.00% 的Java用户
内存消耗:43.3 MB,击败了31.17% 的Java用户

以上解法改编自:https://leetcode.cn/problems/trapping-rain-water/solution/by-ddz16-5c0s/

解法2:双指针

class Solution {
	// 2. 双指针解法
    public int trap(int[] height) {
        // 返回值,雨水总量
        int ans = 0;
        // 左右指针
        int left = 0;
        int right = height.length - 1;
        // 左右最大值
        int leftMax = 0, rightMax = 0;
        // 计算雨水量
        while (left < right) {
            // 哪边小,哪边接雨水
            if(height[left] < height[right]){
                // 从左往右,依次更新左边柱子最大值
                leftMax = Math.max(leftMax, height[left]);
                // 雨水总量 累加 当前可接雨水量 (左侧最大值-当前柱子高度)
                ans += leftMax - height[left];
                // 左指针右移
                left++;
            }else {
                // 从右往左,依次更新右边柱子最大值
                rightMax = Math.max(rightMax, height[right]);
                // 雨水总量 累加 当前可接雨水量 (右侧最大值-当前柱子高度)
                ans += rightMax - height[right];
                // 右指针左移
                right--;
            }
        }
        return ans;
    }
}

解答成功:

  • 执行耗时:0 ms,击败了100.00% 的Java用户
  • 内存消耗:43.7 MB,击败了9.00% 的Java用户
  • 以上解法转载于:https://leetcode.cn/problems/trapping-rain-water/solution/jie-yu-shui-by-leetcode-solution-tuvc/
  • 注释是我个人添加

三、后记

今天AC了一道hard,成就感满满,继续加油啊!!!

龙女辰辰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值