[LeetCode

来源:互联网 发布:淘宝联盟用了红包丢单 编辑:程序博客网 时间:2024/06/14 08:34

1 问题

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.

2 分析

这道题LeetCode网站中给出的解法为 双指针法双指针法在处理字符串类的问题中非常常见。这里着重从数学的角度分析该题目的解法。设容器的面积为S, 且容器由 (i,ai)(j,aj)构成。那么

Si,j=(ji)Min(ai,aj)0i<jn

题目求的是在不同 i,j 下,面积 S 的最大值。如果能够求出函数 S 随着 i,j的增减性,便可以确定 S 的最大值。
下面根据ai,aj的相对大小讨论不同的 i,j 导致 S 的变化情况:

  1. 如果aiaj, 移动 aiai+1:
    1. 如果 ai+1ai,那么 Si+1,j=Si,j(根据S的公式容易判断)
    2. 如果 ai+1<ai, 那么 Si+1,j<Si,j
      即在这种情况下,移动 ai一定不会导致 Si,j 的面积增加
  2. 如果ai<aj, 移动 aiai+1:
    1. 如果 ai<ai+1<aj, 那么 Si+1,j 的面积有可能大于 Si,j
    2. 如果 ai<aj<ai+1, 那么 Si+1,j 的面积一定大Si,j
    3. 如果 ai+1<ai<aj, 那么 Si+1,j 的面积一定小Si,j

根据上述讨论,只有在2.1和2.2的情况下,Si,j 是单调增加的。因此可以将 i,j 分别指向数组的最左和最右端,只按照2.1和2.2的规律来移动 i,j, 便能够求出 S 的最大值。

3 代码

public class Solution {    public int maxArea(int[] height) {        int maxarea = 0, l = 0, r = height.length - 1;        while (l < r) {            maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));            if (height[l] < height[r])                l++;            else                r--;        }        return maxarea;    }}

[1]代码来源于LeetCode: https://leetcode.com/articles/container-most-water/

0 0
原创粉丝点击