Leetcode 11: Container With Most Water

题目链接


题目描述

在这里插入图片描述

解答步骤

这一题刚拿到手,首先想到的是使用两层循环,第一层从左到右遍历作为左柱子,第二层从右往左遍历作为右柱子,记录下最大的容水量并输出即可。这种方法的复杂度将大于O(n^2),不采用

(以下描述中左右柱子指代选定container的左右边界,数组下标从0开始)
接着发现可以添加一些限制条件来减少循环的次数。

  1. 首先,在左柱子选定(依次从左到右遍历)的情况下,假若左柱子的高度低于最右边柱子(size-1),那么没有必要进行循环,以该左柱子为左边界的最大桶必然以size -1 号柱子作为右边界
  2. 假如左柱子高度大于最右边柱子(size - 1),那么则有必要从右向左遍历,找到高度大于右柱子的柱子,计算它与左柱子共同构成的容器的大小是否大于目前最大值,假如大于,则替换
  3. 当新寻找的右柱子高度大于左柱子时,停止遍历
代码

class Solution {
public:
    int maxArea(vector<int>& height) {
    	size = height.size();
    	max = height;
    	for (int i = 0; i < size - 1; ++i)
    	{
			
			max[i] = (height[i] > height[size - 1] ? height[size - 1] : height[i]) * (size - 1 - i);

			if (height[i] > height[size - 1]) {

				int maxRight = size - 1;

				for (int j = size - 1; j > i; --j)
				{
					if (height[j] > height[maxRight]) {
						int temp = (j - i) * (height[i] > height[j] ? height[j] : height[i]);
						if (temp > max[i]) {
							max[i] = temp;
							maxRight = j;
						}
					}

					if ( height[i] <= height[maxRight] ) {
						break;
					}

				}

			}

    	}

    	result = max[0];
    	for (int i = 0; i < size - 1; ++i) {
    		if(max[i] > result){
    			result = max[i];
    		}
    	}

    	return result;   
    }

private:
	std::vector<int> max;
	int size;
	int result;
};

此种方法通过设置限制条件减少了循环的数量,复杂度小于n ^ 2

进一步优化

上面的代码是选定左柱子,进而通过限制条件判定右柱子。但我们可以同时将条件放在左右柱子上。

  1. 假如左柱子高度高于右柱子,那么右柱子应该向左移动。因为左柱子假如向左移动,那么容器的容量只可能减小或不变
  2. 假如左柱子高度低于右柱子,那么左柱子应该向右移动。
代码如下
class Solution {
public:
    int maxArea(vector<int>& height) {
        if (height.size() == 0)
            return 0;
        
        int l = 0, r = height.size()-1;
        int area = 0;
        
        while (l < r){
            int cur = min(height[l], height[r]) * (r - l);
            area = max(area, cur);
            if (height[l] <= height[r])
                l++;
            else
                r--;
        }
        
        return area;
        
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值