《LeetCode之每日一题》:105.接雨水
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:105.接雨水相关的知识,希望对你有一定的参考价值。
题目链接: 接雨水
有关题目
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,
计算按此排列的柱子,下雨之后能接多少雨水。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
n == height.length
0 <= n <= 3 * 10^4
0 <= height[i] <= 10^5
题解
法一:暴力法(超时)
int trap(int* height, int heightSize){
int ans = 0;
for (int i = 1; i < heightSize - 1; i++){
//别忘记置零,放到外面可以拿[0,1,0,2,1,0,1,3,2,1,2,1]的元素2,3,2作为一个例子
int leftMax = 0, rightMax = 0;
for (int j = i; j >= 0; j--){
leftMax = fmax(leftMax,height[j]);//当前坐标i左边的最大值
}
for (int k = i; k < heightSize; k++){
rightMax = fmax(rightMax,height[k]);//当前坐标i右边的最大值
}
ans += fmin(leftMax,rightMax) - height[i];//记录答案
}
return ans;
}
法二:动态规划
思路:
结合上述暴力法求解接雨水的公式,
lmax[i]表示下标自0~i(包含端点)最大值
rmax[i]表示下标自i~n-1(包含端点)最大值
int trap(int* height, int heightSize){
int n = heightSize;
if (n == 0) return 0;
int* lmax = (int*)malloc(sizeof(int) * n);
memset(lmax,0,sizeof(int) * n);
int* rmax = (int*)malloc(sizeof(int) * n);
memset(rmax,0,sizeof(int) * n);
int ans = 0;
//初始值要结合我们动态规划所定义的数组来
lmax[0] = height[0];
rmax[n - 1] = height[n - 1];
for (int i = 1; i < n; i++){
lmax[i] = fmax(lmax[i - 1],height[i]);
}
for (int j = n - 2; j >= 0; j--){
rmax[j] = fmax(rmax[j + 1],height[j]);
}
for (int i = 0; i < n; i++){
ans += fmin(lmax[i],rmax[i]) - height[i];
}
return ans;
}
法三:单调栈
思路:
维护一个单调栈,单调栈存储的是下标,满足从栈底到栈顶的
下标对应的数组height元素递减
//C
int trap(int* height, int heightSize){
int n = heightSize;
if (n == 0) return 0;
int ans = 0;
int stk[n];
int top = 0; //用这个来维护栈
//注意到凹的趋势
for (int i = 0; i < n; i++){
while(top && height[i] > height[stk[top - 1]]){
int stk_top = stk[top - 1];
top--;
if (!top) break;//保证栈内至少存放两个下标
int left = stk[top - 1];
int curWidth = i - left - 1;
int curHeight = fmin(height[i],height[left]) - height[stk_top];
ans += curWidth * curHeight;
}
stk[top++] = i;
}
return ans;
}
法四:双指针
int trap(int* height, int heightSize){
int ans = 0;
int l = 0, r = heightSize - 1;
int lmax = 0, rmax = 0;
while(l < r){
lmax = fmax(lmax,height[l]);
rmax = fmax(rmax,height[r]);
if (lmax < rmax){
ans += lmax - height[l];
l++;
} else {
ans += rmax - height[r];
r--;
}
}
return ans;
}
以上是关于《LeetCode之每日一题》:105.接雨水的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 575. 分糖果 / 237. 删除链表中的节点 / 407. 接雨水 II
2021-07-15:接雨水 II。给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。