leetcode42-接雨水

原题

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

leetcode42-接雨水

上面是由数组 [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

解法

思想

每一列能存下的雨水单位等于左右最高两列当中的较矮一列与当前高度的高度差

leetcode42-接雨水

如图,第五列的积雨水量,等于左边最高一列(第四列left)和右边最高一列(第八列right)的较矮一列(left)与当前列高度的高度差(2-1=1)

如果两边有一边没有比当前列高的列,则当前列不会积水。

代码

我一开始是这样写的:

class Solution {
    public int trap(int[] height) {
        int total = 0;
        int count = height.length;
        Integer[] left = new Integer[count];
        Integer[] right = new Integer[count];
        for(int i = 0;i<count;i++){
            for(int j = 1;j<=i;j++){//更新左边所有列的right
                if(right[j]==null||height[i]>right[j]) right[j] = height[i];
            }
            for(int j = i;j<count-1;j++){//更新右边所有列的left
                if(left[j]==null||height[i]>left[j]) left[j] = height[i];
            }
        }
        for(int i = 0;i<count;i++){
            if(left[i]==null || right[i] == null) continue;
            total += (Math.min(left[i],right[i])-height[i]);
        }
        return total;
    }
}

时间复杂度达到了N2级别,那么如何优化呢?

  1. 不必使用null来表示没有比当前列高的列,即使两列相等,高度差也是0,相当于不积水。
  2. 利用动态规划的思想,如果前一列的left比当前列高,则当前列的left也等于前一列的left。对于right也是一样的。

优化后:

class Solution {
    public int trap(int[] height) {
        int total = 0;
        int count = height.length;
        if(count==0) return 0;
        Integer[] left = new Integer[count];
        Integer[] right = new Integer[count];
        left[0] = height[0];
        right[count-1] = height[count-1];
        for(int i = 1;i<count;i++){//从左向右更新left
            if(height[i]>left[i-1]) left[i] = height[i];
            else left[i] = left[i-1];
        }
        for(int i = count-2;i>=0;i--){//从右向左更新right
            if(height[i]>right[i+1]) right[i] = height[i];
            else right[i] = right[i+1];
        }
        for(int i = 0;i<count;i++){
            total += (Math.min(left[i],right[i])-height[i]);
        }
        return total;
    }
}
func trap(height []int) int {
    lmax := make([]int, len(height))
    rmax := make([]int, len(height))
    for i := 0; i < len(height) - 1; i++{
        lmax[i+1] = max(height[i], lmax[i])
    }
    for i := len(height) -1; i > 0; i--{
        rmax[i-1] = max(height[i], rmax[i])
    }
    sum := 0
    for i := 0; i < len(height); i++{
        long := min(lmax[i], rmax[i]) - height[i]
        if long > 0{
            sum += long
        }
    }
    return sum
}   

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode42-%e6%8e%a5%e9%9b%a8%e6%b0%b4/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年1月22日
下一篇 2020年1月23日

相关推荐

  • leetcode1111-有效括号的嵌套深度

    原题 有效括号字符串 仅由 "(" 和 ")" 构成,并符合下述几个条件之一: 空字符串 连接,可以记作 AB(A 与 B 连接),其中 A 和 B 都是有效括号字符串 嵌套,可以…

    算法 2020年4月1日
    0100
  • leetcode836-矩形重叠

    原题 矩形以列表 [x1, y1, x2, y2] 的形式表示,其中 (x1, y1) 为左下角的坐标,(x2, y2) 是右上角的坐标。 如果相交的面积为正,则称两矩形重叠。需要…

    算法 2020年3月18日
    0450
  • leetcode373-查找和最小的K对数字

    原题 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。 找到和最…

    算法 2020年2月13日
    0160
  • leetcode322-零钱兑换

    原题 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1…

    算法 2020年3月8日
    0150
  • leetcode283-移动零

    原题 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说…

    算法 2019年11月23日
    0110
  • leetcode11-盛最多水的容器

    原题 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i,…

    2020年2月27日
    0250
  • leetcode1162-地图分析

    原题 你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,你知道距离陆地区域…

    2020年3月29日
    0170
  • leetcode260-只出现一次的数字III

    原题 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 示例: 输入: [1,2,1,3,2,5] 输出: [3,5…

    算法 2020年4月28日
    0150
  • 剑指offer57-和为s的连续正数序列

    原题(来源Leetcode) 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。 序列内的数字由小到大排列,不同序列按照首个数字从小到…

    算法 2020年3月6日
    050
  • leetcode78-子集

    原题 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 说明: 解集不能包含重复的子集。 示例: 输入: nums = [1,2,3] 输出: [ [3…

    算法 2020年5月24日
    0310

发表回复

登录后才能评论