42. 接雨水-字节跳动高频题
Posted hequnwang10
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了42. 接雨水-字节跳动高频题相关的知识,希望对你有一定的参考价值。
一、题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [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 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
二、解题
动态规划
对于下标i,下雨后能积水的话,取左右两端的最小值,并且当前值小于左右两边值。使用动态规划,分别计算当前值的左右两边的最大值,当前值的积水量等于min(leftMax[i],rightMax[i])−height[i]。
class Solution
public int trap(int[] height)
//动态规划
int length = height.length;
if(length == 0)
return 0;
int[] leftMax = new int[length];
leftMax[0] = height[0];
for(int i = 1;i<length;i++)
leftMax[i] = Math.max(leftMax[i-1],height[i]);
int[] rightMax = new int[length];
rightMax[length-1] = height[length-1];
for(int i = length-2;i>=0;i--)
rightMax[i] = Math.max(rightMax[i+1],height[i]);
int max = 0;
for(int i = 0;i<length;i++)
max += Math.min(leftMax[i],rightMax[i])-height[i];
return max;
时间复杂度:O(n);
空间复杂度:O(n);
双指针
维护两个下标指针,左右指针,向中间遍历,保存两个变量,leftMax和rightMax 的值。
class Solution
public int trap(int[] height)
int ans = 0;
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
while (left < right)
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
if (height[left] < height[right])
ans += leftMax - height[left];
++left;
else
ans += rightMax - height[right];
--right;
return ans;
时间复杂度:O(n);
空间复杂度:O(1);
栈
单调栈存储的是下标,满足从栈底到栈顶的下标对应的数组 height 中的元素递减。
如果栈内至少有两个元素,记栈顶元素为 top,top 的下面一个元素是 left,则一定有height[left]≥height[top]。如果 height[i]>height[top],则得到一个可以接雨水的区域,该区域的宽度是 i−left−1,高度是 min(height[left],height[i])−height[top]。
class Solution
public int trap(int[] height)
//栈
int ans = 0;
Deque<Integer> stack = new LinkedList<Integer>();
int n = height.length;
for (int i = 0; i < n; ++i)
//判断栈是否为空,并且当前值必须大于栈顶值,这样才能形成低洼
while (!stack.isEmpty() && height[i] > height[stack.peek()])
//低洼处的下标出栈
int top = stack.pop();
//栈为空 跳出循环
if (stack.isEmpty())
break;
//取左边的高度,当前值为右边的高度
int left = stack.peek();
//求面积
int currWidth = i - left - 1;
int currHeight = Math.min(height[left], height[i]) - height[top];
ans += currWidth * currHeight;
//更新右边值
stack.push(i);
return ans;
以上是关于42. 接雨水-字节跳动高频题的主要内容,如果未能解决你的问题,请参考以下文章