法1:和我阿里笔试的优化方法完全一样!阿里实习生笔试
class Solution {//这道题的思路和我阿里笔试的题一模一样,在暴力的基础上用到了dp的思想降低时间复杂度到O(n)
public:
int trap(vector<int>& height) {
int n = height.size();
// left[i]表示i左边的最大值,right[i]表示i右边的最大值
vector<int> left(n, 0), right(n, 0);
for (int i = 1; i < n; i++) {//从前往后
left[i] = max(left[i - 1], height[i - 1]);
}
for (int i = n - 2; i >= 0; i--) {//从后往前
right[i] = max(right[i + 1], height[i + 1]);
}
int water = 0;
for (int i = 0; i < n; i++) {
int level = min(left[i], right[i]);
water += max(0, (level - height[i])*1);
}
return water;
}
};
法2:直接dp,和法1类似
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if (n == 0)return 0;
//定义二维dp数组
//dp[i][0]表示下标i的柱子左边的最大值
//dp[i][1]表示下标i的柱子右边的最大值
vector<vector<int>>dp(n, vector<int>(2, 0));
for (int i = 1; i < n; i++)
{
dp[i][0] = max(dp[i - 1][0], height[i - 1]);
}
for (int i = n - 2; i >= 0; i--)
{
dp[i][1] = max(dp[i + 1][1], height[i + 1]);
}
int water = 0;
for (int i = 0; i < n; i++) {
int level = min(dp[i][0], dp[i][1]);
water += max(0, (level - height[i]) * 1);
}
return water;
}
};