首先这种两边决定当前位置的值的题,很容易想到要用双向dp来做,就是从左到右一次,从右到左一次,然后根据两边的限制来算当前的值。那么这一题我们要的是当前位置左边和右边的最高值,这样用左边和右边最高值的较小值来减去当前的高度就是这个单位长度能盛水的面积。注意我们第二次dp和计算可以和在一起,并且第二次dp不需要维护arr,维护一个滚动变量就可以,扫两遍,时间复杂度O(n),开一个数组,空间复杂度O(n),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Solution { | |
public int trap(int[] A) { | |
if (A == null) | |
return 0; | |
int len = A.length; | |
if (len < 3) | |
return 0; | |
int[] left = new int[len]; | |
int right = 0, sum = 0; | |
for (int i = 1; i < len; i++) | |
left[i] = A[i - 1] >= left[i - 1]? A[i - 1]: left[i - 1]; | |
for (int i = len - 2; i >= 0; i--) { | |
right = A[i + 1] >= right? A[i + 1]: right; | |
int height = left[i] <= right? left[i]: right; | |
int area = A[i] >= height? 0: height - A[i]; | |
sum += area; | |
} | |
return sum; | |
} | |
} |
第二种方法是双指针,比如现在i指向的高度小于j指向的高度,那么从i开始右边的连续递减子序列是肯定可以存水的,并且存水的高度等于i的高度,因为右边必定是有一个高度大于i的高度的墙壁可以挡住水。对于右边也是一样的。时间复杂度O(n),空间复杂度O(1),我们用f[i]表示到i位置左边最高的墙的高度,DP方程为:
- f[i] = max(f[i - 1], A[i - 1]);
- f[0] = 0;
代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Solution { | |
public int trap(int[] A) { | |
if (A == null) | |
return 0; | |
int len = A.length, left = 0, right = len - 1, sum = 0; | |
while (left < right) { | |
int l = A[left]; | |
int r = A[right]; | |
if (l <= r) { | |
while (left < right && A[++left] < l) | |
sum += l - A[left]; | |
} else { | |
while (left < right && A[--right] < r) | |
sum += r - A[right]; | |
} | |
} | |
return sum; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int trap(vector<int>& height) { | |
int len = height.size(), vol = 0; | |
stack<int> st; | |
for(int i = 0; i < len; ++i) | |
{ | |
int curr = height[i]; | |
while(st.size() && height[st.top()] < curr) | |
{ | |
int top = height[st.top()]; | |
while(st.size() && height[st.top()] == top) | |
st.pop(); | |
int width = st.empty()? i : i - st.top() - 1; | |
if(st.size()) | |
vol += width * (min(curr, height[st.top()]) - top); | |
} | |
st.push(i); | |
} | |
return vol; | |
} | |
}; |
No comments:
Post a Comment