LeetCode OJ算法题(十一):Container With Most Water

动态规划解决容器最大水量问题
本文通过动态规划法优化解决经典容器最大水量问题,详细解释了算法逻辑和复杂度优化,提供了一个高效的求解策略。

题目:

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container.

解法:

一看题目就知道,普通的遍历只会TLE,优先考虑动态规划法减少复杂度,理论上可以降至O(n)。指针同时从首尾向中间逼近,当j<=i时,循环终止

设(ai,aj)为面积,那么由观察可以知道,若a(i+1)<=a(i),那么(a(i+1),aj)< (ai,aj),同理,若a(j-1)<= a(j),那么(a(i),a(j-1))< (a(i),a(j)),这些比较是多余的,我们只需要在相对于基点较大的i,j做一下判断足矣。

如果直接这样做,那么难道我们要每一个增大点都比较一次么,形如1,2,3,4,4,3,2,1的序列,实际上并没有降低复杂度。仍需要观察。

以2,3,10,5,7,8,9为例,按照上述比较方法,依次比较的点为(2,9)(2,10)(3,9)(3,10)(10,9),这样一看就很清楚了,(2,10)(3,10)这两次是完全不需要的,因为对于ai<aj的情况,容器的的高度取决于ai,因此j--的变化只会使得容器体积更小。于是我们可以改进条件:

若ai<aj,则i移动到最近的下一个大于ai的点,比较一次;

若ai>aj,则j移动到最近的下一个大于aj的点,比较一次;

外部循环条件为i<j

AC~~~~~~~~~~~~~~~~(⊙o⊙)

public class No11_ContainerWithMostWater {
	public static void main(String[] args){
		System.out.println(maxArea(new int[]{1,2}));
	}
	public static int maxArea(int[] height){
		int i = 0, j = height.length-1;
		int start = height[i];
		int end = height[j];
		int max = (start<end?start:end)*(j-i);
		while(i<j){
			if(height[i] <= height[j]){
				while(height[i] <= start && i<j) i++;
				if(height[i] > start)
					start = height[i];
			}
			else{
				while(height[j] <= end && i<j) j--;
				if(height[j] > end)
					end = height[j];
			}
			if(max < (start<end?start:end)*(j-i))
				max = (start<end?start:end)*(j-i);
		}
		return max;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值