LeetCode Trapping Rain Water

本文探讨了LeetCode中关于计算可以捕获多少雨水的问题。提出了两种解决方案:一种是逐层计算面积的方法,虽然时间复杂度较高,但能够通过测试;另一种是采用分治思想,寻找最大两个元素间的面积,递归计算左右两侧剩余部分。文章提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

accept?真是一阵惊喜,没想到这方法能通过,而且反应了有一会儿。先回顾一下前面的相关的题目http://oj.leetcode.com/problems/container-with-most-water/   http://blog.youkuaiyun.com/littlestream9527/article/details/17174075  这题当然不一样了,首先每个元素本身都要占据面积的,其次不是求最值,没有趋向性;像这种82503502503509,两个高墙之间夹多个隔槽的怎么分呢,最多的水肯定是在两个高槽的位置,关键是找中间的墙占多大的面积,一想有点复杂我就从另一个角度入手了。我是这样想的:一层一层地算面积,先算高度最小的那层的面积,再算上一层高度的(注意,上一层高度和下一层高度没什么关系,要把下一层的高度减去),这样一直到最大的高度(其实到的二大的高度就行了)。这复杂度其实不低,O(n)*高度的数量。好歹下面的代码通过了。可能会有更好的吧,明天再说。

int trap(int A[], int n) {
	set<int> st;
	for (int i=0;i<n;i++)
	{
		st.insert(A[i]);
	}
	int sum = 0;
	set<int>::iterator iter = st.begin();
	int height=0,lastheight=0;
	while(iter!=st.end())
	{
		height = *iter;// - lastheight;
		int i=0;
		while(i<n&&A[i]<height)//looking for the first higher than layer
			i++;
		while(i<n)
		{
			while(i<n&&A[i]>=height)// looking for  the first lower than layer
				i++;
			--i;
			int j = i + 1;
			while(j<n&&A[j]<height)// looking for the first higher than layer
				j++;
			if (j<n)
			{
				sum += (j-i-1)*(height - lastheight);// each time one layer
			}
			i = j;
		}
		lastheight = height;
		iter++;
	}
	return sum;
}

第二种方法,自己想的,思想应该是分治思想,首先找最大的两个元素位置,这两个之间的面积可求,然后求左侧剩下的和右侧剩下的,整体和就是所求的解。如下:

int reversive_trap(int *arr,int start,int end)
{
	if (start>=end||start + 1==end)
	{
		return 0;
	}
	int maxheight = arr[start],secondeheight= 0;
	int maxpos = start, secondpos = start+1;
	for (int i=start+1;i<=end;i++)
	{
		if (maxheight<=arr[i])
		{
			secondeheight = maxheight;
			secondpos = maxpos;
			maxheight = arr[i];
			maxpos = i;
		}
		else
		{
			if (secondeheight<arr[i])
			{
				secondeheight = arr[i]; 
				secondpos = i;
			}
		}
	}
	int leftpos = secondpos,rightpos = maxpos;
	int height = secondeheight;
	if (leftpos > rightpos)
	{
		leftpos = maxpos;
		rightpos = secondpos;
	}
	int sum=0;
	sum = height * (rightpos - leftpos - 1);
	for (int j=leftpos+1;j<rightpos;j++)
	{
		sum -= arr[j];
	}
	return sum + reversive_trap(arr,start,leftpos) + reversive_trap(arr,rightpos,end);
}

int trap(int A[], int n) {
	return reversive_trap(A,0,n-1);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值