leetcode 11. Container With Most Water 双指针 + 最短木桶理论

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) 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 and n is at least 2.

这道题的大致意思就是寻找可能组成最大桶的位置,最简单的就是暴力求解,这个是我想出来的方法(肯定也是一般人都能想到的方法),不过我网上看了其他人的解法,发现有一个双指针的解决方法。

大致思路就是使用指向数组头部和尾部的双向指针,不断收缩,在搜索过程中得到最优解。收缩策略是:如果 height[beg] < height[end] ,beg++,否者end–。 为什么这个策略可以求出最优值呢?网上的说法是:用两个指针从两端开始向中间靠拢,如果左端线段短于右端,那么左端右移,反之右端左移,知道左右两端移到中间重合,记录这个过程中每一次组成木桶的容积, 返回其中最大的。 我的理解是:按照这种策略收缩,才可能出现最优值,这个策略的主要就是提高最低木板的高度,每次搜索后的结果不一定都要比之前的要好,但是全局的最优解一定出现在某一次的搜索过程中。

代码如下:

public class Solution
{
    /*
     * 答案是有,用两个指针从两端开始向中间靠拢,如果左端线段短于右端,那么左端右移,
     * 反之右端左移,知道左右两端移到中间重合,记录这个过程中每一次组成木桶的容积,
     * 返回其中最大的。(想想这样为何合理?)
     * 合理性解释:当左端线段L小于右端线段R时,我们把L右移,这时舍弃的是L与右端其他
     * 线段(R-1, R-2, ...)组成的木桶,这些木桶是没必要判断的,因为这些木桶的容积
     * 肯定都没有L和R组成的木桶容积大。
     * */
    public int maxArea(int[] height) 
    {
        if(height==null || height.length<=1)
            return 0;
        int i=0,j=height.length-1,max=0;
        while(i<j)
        {
            max=Math.max(max, (j-i)*Math.min(height[i], height[j]));
            if(height[i]<height[j])
                i++;
            else
                j--;
        }
        return max; 
    }


    /*
     * 暴力求解肯定超时
     * */
    public int maxAreaByBaoLi(int[] height) 
    {
        if(height==null || height.length<=1)
            return 0;

        int maxArea=-1;
        for(int i=0;i<height.length;i++)
        {
            for(int j=i+1;j<height.length;j++)
            {
                maxArea=Math.max(maxArea, (j-i)*(Math.min(height[j],height[i])));
            }
        }
        return maxArea;

    }


    public static void main(String[] args) 
    {
        Solution so=new Solution();
        int []a={1,1};
        System.out.println(so.maxArea(a));
    }
}

下面的是C++的做法,就是使用双指针来计算最大值,这个使用了最短木桶理论, 这道题必须掌握。

代码如下:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution 
{
public:
    int maxArea(vector<int>& height)
    {
        int maxArea = 0;
        int beg = 0, end = height.size() - 1;
        while (beg < end)
        {
            maxArea = max(maxArea, (end-beg)*min(height[beg], height[end]));
            if (height[beg] < height[end])
                beg++;
            else
                end--;
        }

        return maxArea;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值