LeetCode42.接雨水

思路一:暴力破解

首先我们要找一个最高的柱子,将整个柱子堆划分为2部分,即左部分和右部分,我们分别来统计左右部分可以装的总水量,

以左部分为例:我们从左部分开头开始,向右遍历至中间最高处,

情况1.我们所走的当前位置如果前面有比它高的,那就用

前面最高的高度-当前高度 所得的结果就是这个格子能装的水的高度

情况2.如果所走的位置比前面最高的还高,那就将最高的记做当前的柱子,再走下一个

有部分:和左部分一样,只不过从右向左走。遇到的情况还是一样

/*
	 * 先找出最高的柱子,左边从左往右,如果该柱子低于前面最高的
	 * 则存水量为前面最高的减去这个柱子,右边总右向左走
	 */
	public int trap(int[] height) {
		int begin=0,end=height.length-1;
		int max=0,maxval=0;
		//找到最大值和最大值得下标
		for(int i=0;i<height.length;i++) {
			if(height[i]>maxval) {
				max=i;maxval=height[i];
			}
		}
		int sum=0;
		int flag=0;//前面最高的柱子
		//从左往右找
		for(int i=0;i<max;i++) {
			if(height[i]<flag) {//如果这个柱子小于前面最高的
				sum=sum+(flag-height[i]);
			}
			if(height[i]>=flag)//如果大于等于最高的
				flag=height[i];
		}
		flag=0;
		for(int i=height.length-1;i>max;i--) {
			if(height[i]<flag)//如果这个柱子小于前面最高的
				sum=sum+(flag-height[i]);
			if(height[i]>=flag)//如果大于等于最高的
				flag=height[i];
		}
		return sum;
    }

 

思路二:使用栈

参考:https://www.jianshu.com/p/024d2e3c13e8

类似于括号匹配问题,先找上升趋势,将其入栈,直到找到下降的,那么这个下降的柱和上升的柱之间一定存在一个坑,我们就要计算这个坑,然后进一步扩大,计算中间的坑,最后将所有的坑加起来,就是所有的总和。

具体的讲解在上面的博客中讲了。

下面是具体的代码

//利用堆栈的方法
	public int trap2(int[] height) {
		//用来存储height的下标
		Stack<Integer> stack=new Stack<>();
		int sum=0;
		//遍历数组
		for(int i=0;i<height.length;i++) {
			//如果数组为空或者数组是递减顺序
			if(stack.isEmpty()||height[i]<height[stack.peek()]) {
				stack.push(i);//此处记录的是数组的下标
			}else{//当数组不为递减顺序时,就需要弹栈了
				while(!stack.isEmpty()&&height[i]>height[stack.peek()]) {
					int pre=stack.pop();//弹出栈顶元素
					if(!stack.isEmpty()) {//因为此处要使用栈前面的元素
						sum+=(min(height[i],height[stack.peek()])-height[pre])*(i-stack.peek()-1);
					}
				}
				stack.push(i);
			}
		}
		return sum;
	}
	private int min(int a,int b) {
		return a<b?a:b;
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值