题目:leetcode 42题
解法一:动态规划
int trap(vector<int>& height) {
int ans = 0;
int size = height.size();
if(size)
{
vector<int> max_left(size);
vector<int> max_right(size);
max_left[0] = height[0];
max_right[size-1] = height[size-1];
for(int i=1;i<size;i++)
max_left[i] = max(max_left[i-1],height[i]); 使用迭代的思想。
for(int i=size-2;i>-1;i--)
max_right[i] = max(max_right[i+1],height[i]); 使用迭代的思想。
for(int i=0;i<size;i++)
ans += min(max_left[i],max_right[i])-height[i];
}
return ans;
}
思路分析:
每一个水柱之所以能够接水是因为每一个水柱的左边和右边个存在一个或者多个比自己高的水柱,选取左边的一个和右边较低的
那个水柱就是当下这个水柱接水能达到的最大高度。那么解题的思路就出来了,建立两个数组,一个数组依次存放当下水柱左边
最高的水柱的索引,一个数组依次存放当下水柱右边最高的水柱的索引。最后同时遍历这两个数组,将每一个水柱的接水量累加
求和就是最后结果!
复杂性分析:
时间复杂性分析:
O(n):存储最大高度数组和遍历存储的数组。
空间复杂性分析:
O(n):使用了两个存储最大高度的数组作为额外存储空间。
解法二:使用stack
int trap(vector<int>& height) {
int ans = 0;
int size = height.size();
stack<int> st;
for(int cur=0;cur<size;cur++)
{
while(!st.empty() && height[cur]>height[st.top()])
{
int temp = st.top();
st.pop();
if(st.empty())
break;
int width = cur-st.top()-1;
int high = min(height[cur],height[st.top()])-height[temp];
ans += width*high;
}
st.push(cur);
}
return ans;
}
思路分析:
和动态规划类似,栈里面负责存储比当前元素的大水柱,就是先入栈的水柱一定比后入栈的水柱大,这样相当于把每一个水柱左边
的比自己高的水柱全都放在了栈里面,每当遇到一个右边的水柱比自己高的时候,就求一下在当前离自己最近的两个比自己高的水
柱的相夹的面积内接了多少雨水,这样依此类推下去,将所有接到的雨水累计就是结果。
复杂性分析:
时间复杂性:
O(n):遍历了一遍数组。
空间复杂性:
O(n):使用了stack作为额外的存储空间。
出现了错误的地放还请不吝指正!谢谢
原文地址:https://www.cnblogs.com/cccf/p/12700654.html
时间: 2024-10-16 10:58:28