Leetcode42. 接雨水(dp+双指针)

Posted !0 !

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode42. 接雨水(dp+双指针)相关的知识,希望对你有一定的参考价值。

题目链接:https://leetcode-cn.com/problems/trapping-rain-water/

解题思路

我们可以发现每个点的面积等于左右两边最大高度的较小值减去当前点的高度。当前点的高度我们是知道的,所以就只要求出当前点的左右两边的最大高度的较小值就行。

方法一:动态规划

我们直接用两个数组记录每个点的左边和右边的最大值。虽然是动态规划,但是还是很简单的动态规划。

代码

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        if (n == 0) return 0;   //特判
        int[] lMax = new int[n];    //左边最大值
        lMax[0] = height[0];    //因为第一个元素左边没有值所以就直接初始化成第一个元素
        for (int i = 1; i < n; i++)     //寻找左边的最大值
            lMax[i] = Math.max(lMax[i - 1], height[i]);
        int[] rMax = new int[n];    //右边最大值
        rMax[n - 1] = height[n - 1];    //因为最后一个元素右边没有值所以就直接初始化成最后一个元素
        for (int i = n - 2; i >= 0; i--) //寻找左边的最大值
            rMax[i] = Math.max(rMax[i + 1], height[i]);
        int ans = 0;
        for (int i = 0; i < n; i++)     //计算每个点的面积
            ans += Math.min(lMax[i], rMax[i]) - height[i];
        return ans;
    }
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

方法二:双指针

双指针算法把空间复杂度优化成了常数级别,非常的巧妙。
左右两个分别指向左右两个边界,比较左右指针高度,高度小的往中间移一格,并且计算最高的高度与它的高度只差。

代码

class Solution {
    public int trap(int[] height) {
        int ans = 0;
        int l = 0, r = height.length - 1;
        int lMax = 0, rMax = 0; //分别记录左右最大值
        while (l < r) {
            lMax = Math.max(lMax, height[l]);   //更新左边最大值
            rMax = Math.max(rMax, height[r]);   //更新右边最大值
            if (height[l] < height[r]) {    //左边高度比右边小
                ans += lMax - height[l];    //计算左边最大高度与当前高度差
                ++l;
            } else {
                ans += rMax - height[r];    //计算右边最大高度与当前高度差
                --r;
            }
        }
        return ans;
    }
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

以上是关于Leetcode42. 接雨水(dp+双指针)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 42. 接雨水(双指针动态规划单调栈)

leetcode42 接雨水

LeetCode:接雨水42

leetcode 每日一题 42. 接雨水

leetcode 每日一题 42. 接雨水

LeetCode 42 接雨水