• 42. 接雨水


    题目描述查看:https://leetcode-cn.com/problems/trapping-rain-water/

      题目的意思是给定一个数组,数组值表示柱子的高度,问能盛多少水。

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

    • 思路

      按照列来看,每一列能盛多少水,取决于它左边柱子的最大值leftMax和右边柱子的最大值rightMax,leftMax和rightMax里小的那个又决定水能有多高(木桶,能装多少水,短的说了算)。根据这个思路,只要知道每个柱子左边的最大值leftMax和右边的最大值rightMax,就能求解能装多少水了。

    leftMax和rightMax的求解

     1         leftMax[0] = height[0];
     2         rightMax[height.length-1] = height[height.length-1];
     3         //比当前柱子和前一个柱子的leftMax,找到当前柱子的左最大值
     4         for (int i = 1; i < height.length-1; i++) {
     5             leftMax[i] = Math.max(leftMax[i-1],height[i]);
     6         }
     7         //右最大值是从当前柱子往右比,所以要从最右边的开始求
     8         //比当前柱子和前一个柱子的rightMax,找到当前柱子的右最大值
     9         for (int i = height.length -2;i > 0; i--) {
    10             rightMax[i] = Math.max(rightMax[i+1],height[i]);
    11         }
    • 边界条件

    2个元素,没法装水。

    if(height.length < 3)return 0;

    3个元素,装水值取决于height[0]和height[2]的高度,如果height[1]>=min(height[0],height[2]),没法装水。

    if(height.length == 3)return Math.min(height[0],height[2]) - height[1] > 0 ?Math.min(height[0],height[2]) - height[1]:0;
    • 代码

     1     public int trap(int[] height) {
     2         int[] leftMax = new int[height.length];
     3         int[] rightMax = new int[height.length];
     4         if(height.length < 3)return 0;
     5         if(height.length == 3)return Math.min(height[0],height[2]) - height[1] > 0 ?Math.min(height[0],height[2]) - height[1]:0;
     6         int water = 0;
     7         leftMax[0] = height[0];
     8         rightMax[height.length-1] = height[height.length-1];
     9         //比当前柱子和前一个柱子的leftMax,找到当前柱子的左最大值
    10         for (int i = 1; i < height.length-1; i++) {
    11             leftMax[i] = Math.max(leftMax[i-1],height[i]);
    12         }
    13         //右最大值是从当前柱子往右比,所以要从最右边的开始求
    14         //比当前柱子和前一个柱子的rightMax,找到当前柱子的右最大值
    15         for (int i = height.length -2;i > 0; i--) {
    16             rightMax[i] = Math.max(rightMax[i+1],height[i]);
    17         }
    18 
    19         for (int i = 1; i < height.length - 1; i++) {
    20             int h = Math.min(leftMax[i],rightMax[i]);
    21             if(h > height[i])water += h- height[i];
    22         }
    23         return water;
    24     }
  • 相关阅读:
    bzoj4758: [Usaco2017 Jan]Subsequence Reversal(区间dp)
    bzoj4580: [Usaco2016 Open]248(区间dp)
    1617: [Usaco2008 Mar]River Crossing渡河问题(dp)
    bzoj21012101: [Usaco2010 Dec]Treasure Chest 藏宝箱(滚动数组优化dp)
    P2339 提交作业usaco(区间dp)
    day11
    bzoj2330: [SCOI2011]糖果(差分约束)
    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm(Tarjan+记忆化)
    P2700逐个击破(并查集/树形dp)
    bzoj1770: [Usaco2009 Nov]lights 燈(折半搜索)
  • 原文地址:https://www.cnblogs.com/vshen999/p/12618794.html
Copyright © 2020-2023  润新知