• LeetCode-Container With Most Water-zz


    先上代码。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 class Solution {
     7 public:
     8     int maxArea(vector<int> &height) {
     9         if (height.empty()) return 0;
    10         int i = 0, j = height.size() - 1;
    11         int max = INT_MIN;
    12         int area;
    13         while (i < j)
    14         {
    15             area = min(height[i],height[j])*(j-i);
    16             if (area>max) max = area;
    17             if (height[i] < height[j]) i++;//谁是短板,谁就该移动
    18             else j--;
    19         }
    20         return max;
    21     }
    22 };
    23 
    24 int main()
    25 {
    26     Solution s;
    27     int array[] = {2,5,3,1,6};
    28     vector<int> h(array,array+5);
    29     cout << s.maxArea(h)<<endl;
    30     return 0;
    31 }

    http://blog.unieagle.net/2012/09/16/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Acontainer-with-most-water/

    最笨的方法是暴力破解,加上一点预判。时间是O(n^2)

    看了nandawys的评论,找到了O(n)方法,思路是从两头到中间扫描,设i,j分别指向height数组的首尾。
    那么当前的area是min(height[i],height[j]) * (j-i)。
    当height[i] < height[j]的时候,我们把i往后移,否则把j往前移,直到两者相遇。

    这个正确性如何证明呢?
    代码里面的注释说得比较清楚了,即每一步操作都能保证当前位置能取得的最大面积已经记录过了,而最开始初始化的时候最大面积记录过,所以有点类似于数学归纳法,证明这个算法是正确的。



    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.



    代码
    600ms过大集合

    class Solution {
    public:
        int maxArea(vector<int> &height) {
            // Start typing your C/C++ solution below
            // DO NOT write int main() function
            int max = 0;
            for( int i = 0 ; i < height.size(); ++i)
            {
                int hi = height[i];
                if(hi == 0)
                    continue;
                int minPosibleIndex = max / hi + i;
                for(int j = height.size() - 1; j > i && j >= minPosibleIndex; --j)
                {
                    int hj = height[j];
                    int area = min(hi,hj) * (j - i);
                    if (area > max)
                        max = area;
                }
            }
            return max;
        }
    };



    Code rewrite at 2013-1-4,O(n)

     1 class Solution {
     2 public:
     3     int maxArea(vector<int> &height) {
     4         if (height.size() < 2) return 0;
     5         int i = 0, j = height.size() - 1;
     6         int maxarea = 0;
     7         while(i < j) {
     8             int area = 0;
     9             if(height[i] < height[j]) {
    10                 area = height[i] * (j-i);
    11                 //Since i is lower than j, 
    12                 //so there will be no jj < j that make the area from i,jj 
    13                 //is greater than area from i,j
    14                 //so the maximum area that can benefit from i is already recorded.
    15                 //thus, we move i forward.
    16                 //因为i是短板,所以如果无论j往前移动到什么位置,都不可能产生比area更大的面积
    17                 //换句话所,i能形成的最大面积已经找到了,所以可以将i向前移。
    18                 ++i;
    19             } else {
    20                 area = height[j] * (j-i);
    21                 //the same reason as above
    22                 //同理
    23                 --j;
    24             }
    25             if(maxarea < area) maxarea = area;
    26         }
    27         return maxarea;
    28     }
    29 };
  • 相关阅读:
    心跳机制
    有可能出现的中文乱码
    【学习】logger
    【开发效率】Chrome快捷键
    Unable to open debugger port (127.0.0.1:4184): java.net.SocketException "socket closed"
    将项目发布【2.用idea】
    将项目发布【1.用MobaXterm】
    basePath
    大文件上传如何做断点续传?
    JavaScript如何判断一个元素是否在可视区域中?
  • 原文地址:https://www.cnblogs.com/forcheryl/p/4017817.html
Copyright © 2020-2023  润新知