java 暴力解法+备忘录+双指针
参考解法labuladong
1)暴力解法
public int trap(int[] height) {
int len = height.length;
int ret=0;
int l_max=0;
int r_max=0;
//遍历数组,每遍历到一个位置,都计算该位置前后最大高度
for(int i=0;i<len;i++) {
//寻找该位置左边最大高度
for(int j=i;j>=0;j--) {
l_max=Math.max(l_max, height[j]);
}
//寻找该位置右边最大高度
for(int j=i;j<len;j++) {
r_max=Math.max(r_max, height[j]);
}
ret+=Math.min(l_max, r_max)-height[i];
l_max=0;
r_max=0;
}
return ret;
}
时间复杂度O(N^2)
LeetCode执行用时88ms,击败6.75%
2)备忘录
public int trap(int[] height) {
int len = height.length;
if(len<=2)return 0;
int ret=0;
int[] l_max=new int[len];
l_max[0]=height[0];
int[] r_max=new int[len];
r_max[len-1]=height[len-1];
//动态规划计算每个位置的左边的最大高度
for(int i=1;i<len;i++) {
l_max[i]=Math.max(l_max[i-1], height[i]);
}
//动态规划计算每个位置的右边的最大高度
for(int i=len-2;i>0;i--) {
r_max[i]=Math.max(r_max[i+1], height[i]);
}
for(int i=1;i<len-1;i++) {
ret+=Math.min(l_max[i], r_max[i])-height[i];
}
return ret;
}
时间复杂度O(N)
LeetCode执行用时1ms,击败99.90%
3)双指针
public int trap(int[] height) {
int len = height.length;
if(len<=2)return 0;
int ret=0;
int left=0, right=len-1;
int l_max=height[0];
int r_max=height[len-1];
while(left<=right) {
l_max=Math.max(l_max, height[left]);
r_max=Math.max(r_max, height[right]);
if(l_max<r_max) {
ret+=l_max-height[left];
left++;
}else {
ret+=r_max-height[right];
right--;
}
}
return ret;
}
时间复杂度O(N)
LeetCode执行用时2ms,击败35.87%