您的位置:首页 > 移动开发

leetcode--trapping_rain_water

2016-12-05 09:47 295 查看
题意: 给定n个由非负整数表示的正视图,每一个块的宽度是1,计算可以放多少水。

举例: 给定一个数组[0, 1, 0, 2, 1, 0 , 1, 3, 2, 1, 2, 1],返回6,图示如下:



分析: 本题的标注是栈,我一开始也是往栈的方向去想,虽然可以实现,但是比较繁琐。做完之后参考其他算法大牛的做法,发现可以使用时间复杂度是O(n),空间复杂度是O(1)的方法,更加高效。算法思想是:先遍历一趟数组,找到最高的,然后将数组从最高处分成左右两部分,分别计算左边的和右边的容量,左边的可以从起始位置向最高位置遍历,右边的从末端位置向最高处遍历,经过这两趟遍历即可求得最终解。算法思路比较清晰,也容易理解,需要记下来这种解题方法。

代码

先贴上我自己的代码吧,虽然比较复杂…

import java.util.Stack;
public class Solution {
public int trap(int[] A) {
Stack<Integer> stack = new Stack<>();
if(A == null || A.length == 0){
return 0;
}else{
stack.push(A[0]);
int height = A[0];
int result = 0;
for(int i = 1; i < A.length; i++){
if(A[i] < height){       //如果当前值小于height,就加入栈当中
stack.push(A[i]);
}else{                  //如果当前值大于等于height,那就说明可以存水
while(!stack.isEmpty()){
result += height - stack.pop(); //可以盛放多少水等于当前的高度height减去小方块的高度
}
stack.push(A[i]);
height = A[i];  //修改高度
}
}
height = stack.pop();   //到最后都没有比当前height更高以后,从栈顶向栈底走逐步求可容纳的水量
while(!stack.isEmpty()){
int temp = stack.pop();
if(temp <= height) result += height - temp;
else{
height = temp;
}
}
return result;
}

}
}


源程序下载

更高效的一个算法实现

虽然是C++版本的,不过基本和java的一样,除了定义类和方法时略有不同。

class Solution {
public:
int trap(int heights[], int n) {
int maxhigh=0;
int left=0,right=0;
for(int i=0;i<n;i++)//找到最大值的下标
{
if(heights[i]>heights[maxhigh])
maxhigh=i;
}
int sum=0;
for(int i=0;i<maxhigh;i++)//计算左边的容量
{
if(heights[i]<left)
sum+=(left-heights[i]);
else
left=heights[i];
}

for(int j=n-1;j>maxhigh;j--)//计算右边的容量
{
if(heights[j]<right)
sum+=(right-heights[j]);
else
right=heights[j];
}
return sum;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: