【前言】:本文讲解【动态规划】及其改进版【双指针】,时间复杂度均为O(n),空间复杂度前者为O(n)、后者为O(1)。
一、题目描述
牛客版描述:给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图。计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度均视为0)
力扣版描述:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
1. 要求
数据范围:数组长度 0 <= n <= 2*105,数组中每个值满足 0 < val <= 109
要求:时间复杂度 O(n)
2. 样例
输入: arr = [3,1,2,5,2,4]
输出: 5
输入: arr = [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
二、动态规划
对于某个柱子arr[ i ]而言,计算它能接的水cap[ i ]其实只需要找它左边的最大值iLeft和右边的最大值iRight,这两个最大值就像木桶的两块木板把arr[ i ]夹在中间决定了cap[ i ]的上限,而具体能接到多少则取决于两者的最小值(短板效应),即 cap[ i ] = min ( iLeft , iRight )。
因此解题时只需要定义两个数组leftMax和rightMax,从左往右地遍历arr数组,找到每个arr[ i ]左边的最大值存入leftMax;再从右往左地遍历arr数组,找到每个arr[ i ]右边的最大值存入rightMax。最后再次遍历arr数组计算每个arr[ i ]的接水量,累加起来就是最终结果ret。
时间复杂度:O(n) 3次遍历数组
空间复杂度:O(n) 2个辅助数组
class Solution {
public int trap(int[] arr) {
// 找出每个arr[i]左边的最大值(包含它自己)
int[] leftMax = new int[ arr.length
本文详细解析动态规划与双指针方法解决接雨水问题,时间复杂度均为O(n)。动态规划涉及3次遍历,空间复杂度O(n),而双指针方法只需1次遍历,空间复杂度O(1)。


最低0.47元/天 解锁文章
552

被折叠的 条评论
为什么被折叠?



