【力扣】42. 接雨水

以下为官方思路之一,及本人代码

42. 接雨水

  • 题目
    • 题意
    • 示例 1
    • 示例 2
    • 提示
  • 官方题解
    • 双指针
      • 算法总结
      • 复杂度
  • 本人代码
    • Java
    • 提交结果:通过

题目

题意

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

示例 1

【力扣】42. 接雨水_第1张图片

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

示例 2

输入 h e i g h t = [ 4 , 2 , 0 , 3 , 2 , 5 ] height = [4,2,0,3,2,5] height=[4,2,0,3,2,5]
输出 9 9 9

提示

  1. n = = h e i g h t . l e n g t h n == height.length n==height.length
  2. 1 < = n < = 2 ∗ 1 0 4 1 <= n <= 2 * 10^4 1<=n<=2104
  3. 0 < = h e i g h t [ i ] < = 1 0 5 0 <= height[i] <= 10^5 0<=height[i]<=105

官方题解

双指针

算法总结

  1. 初始化两个指针 l e f t = 0 left = 0 left=0 r i g h t = h e i g h t . l e n g t h − 1 right = height.length - 1 right=height.length1
  2. l e f t < r i g h t left < right left<right 时向中间移动两个指针:
    2.1 如果 h e i g h t [ l e f t ] < h e i g h t [ r i g h t ] height[left] < height[right] height[left]<height[right],说明储水量依赖于 h e i g h t [ l e f t ] height[left] height[left] 的高度(可能构成低洼的右边界很大)
    2.1.1 如果 h e i g h t [ l e f t ] > l e f t M a x height[left] > leftMax height[left]>leftMax 说明没有或超出左边边界,不构成低洼, l e f t M a x = h e i g h t [ l e f t ] leftMax = height[left] leftMax=height[left]
    2.1.2 如果 h e i g h t [ l e f t ] < = l e f t M a x height[left] <= leftMax height[left]<=leftMax 说明构成低洼,往答案中累加积水量。 a n s + = l e f t M a x − h e i g h t [ l e f t ] ans += leftMax - height[left] ans+=leftMaxheight[left]
    2.1.3 前进 l e f t left left l e f t + + left++ left++
    2.2 如果 h e i g h t [ l e f t ] > = h e i g h t [ r i g h t ] height[left] >= height[right] height[left]>=height[right],说明储水量依赖于 h e i g h t [ r i g h t ] height[right] height[right] 的高度(可能构成低洼的左边界很大)
    2.2.1 如果 h e i g h t [ r i g h t ] > r i g h t M a x height[right] > rightMax height[right]>rightMax 说明没有或超出右边边界,不构成低洼, r i g h t M a x = h e i g h t [ r i g h t ] rightMax = height[right] rightMax=height[right]
    2.2.2 如果 h e i g h t [ r i g h t ] < = r i g h t M a x height[right] <= rightMax height[right]<=rightMax 说明构成低洼,往答案中累加积水量。 a n s + = r i g h t M a x − h e i g h t [ r i g h t ] ans += rightMax - height[right] ans+=rightMaxheight[right]
    2.2.3 前进 r i g h t right right r i g h t − − right-- right

复杂度

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 h e i g h t height height 的长度。两个指针的移动总次数不超过 n n n
  • 空间复杂度: O ( 1 ) O(1) O(1)。只需要使用常数的额外空间。

本人代码

Java

class Solution {
    public int trap(int[] height) {
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        int ans = 0;

        while (left < right) {
            if (height[left] < height[right]) {
                if (height[left] >= leftMax) {
                    leftMax = height[left];
                } else {
                    ans += leftMax - height[left];
                }
                left++;
            } else {
                if (height[right] >= rightMax) {
                    rightMax = height[right];
                } else {
                    ans += rightMax - height[right];
                }
                right--;
            }
        }

        return ans;
    }
}

提交结果:通过

  • 执行用时: 1 m s 1ms 1ms
  • 内存消耗: 42.42 M B 42.42MB 42.42MB

你可能感兴趣的:(力扣,leetcode,算法)