zoukankan      html  css  js  c++  java
  • LeetCode11 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.

    分析:

    自己做的时候脑子并不是很清楚(帮老板画图画的...),不过一步一步优化也算AC了。但是看着跑的时间那么高就知道肯定不是最优,

    学习讨论区后知道了O(n)算法的思路并实现,思考历程记录如下:

    1.暴力先写一个,把所有区间来一遍,O(n^2)。当然肯定超时...代码还是记录一下吧

     1 class Solution {
     2 public:
     3     int maxArea(vector<int>& height) {
     4         int result = 0;
     5         for (int i = 1; i < height.size(); ++i) {
     6             for (int j = 0; j < i; ++j) {
     7                 int h = i - j;
     8                 int l = min (height[i], height[j]);
     9                 result = max(result, h * l);
    10             }
    11         }
    12         return result;
    13     }
    14 };

    2. 不按照区间走,按照不同高度,高度依次向上时,找到符合该高度的最长区间(两头扫),然后比较。

    高度用个map存,代码如下:(分析时间复杂度O(m*n*logm) m不同高度的数量),诸如1,2,3...15000全是不同高度数字的样例也会超时

    class Solution {
    public:
        int maxArea(vector<int>& height) {
            set<int> s;
            for (int i = 0; i < height.size(); ++i) {
                s.insert(height[i]);
            }
            auto itr = s.begin();
            int result = (*itr) * (height.size() - 1);
            for ( itr = s.begin(); itr != s.end(); ++itr) {
                 int left = 0, right = height.size() - 1;
                 while (height[left] < (*itr) ) {
                     ++left;
                 }
                 while (height[right] < (*itr) ) {
                     --right;
                 }
                 result = max(result, (right - left) * (*itr) );
            }
            return result;
        }
    };

    3.分析上述代码,其实left,right这里根本没必要每次都从头遍历。因为height是递增的,所以left,right在上一次基础上继续走即可。

    所以代码内层只需一遍遍历,复杂度O(m*logm),这个可以AC了。

     1 class Solution {
     2 public:
     3     int maxArea(vector<int>& height) {
     4         set<int> s;
     5         for (int i = 0; i < height.size(); ++i) {
     6             s.insert(height[i]);
     7         }
     8         auto itr = s.begin();
     9         int result = 0;
    10         int left = 0, right = height.size() - 1;  //这句优化!
    11         for (itr = s.begin(); itr != s.end(); ++itr) {
    12              while (height[left] < (*itr) ) {
    13                  ++left;
    14              }
    15              while (height[right] < (*itr) ) {
    16                  --right;
    17              }
    18              result = max(result, (right - left) * (*itr) );
    19         }
    20         return result;
    21     }
    22 };

    4.实际上,也没有必要按照高度存储和遍历。

    注意到如果从最大长度区间开始向内遍历,只有当高度更高时才有可能更新面积(因为长度已经比之前小),所以,两根指针一遍遍历即可。O(n)

    代码:

     1 class Solution {
     2 public:
     3     int maxArea(vector<int>& height) {
     4         int i = 0, j = height.size() - 1, result = 0;
     5         while (i < j) {
     6             int minHeight = min(height[i], height[j]);
     7             result = max(result, minHeight * (j - i));
     8             while (height[i] <= minHeight) {
     9                 i++;
    10             }
    11             while (height[j] <= minHeight) {
    12                 j--;
    13             }
    14         }
    15         return result;
    16     }
    17 };
  • 相关阅读:
    PHP开发经常遇到的几个错误
    PHP的Trait
    PHP反射API
    php split 和 explode 的区别
    php判断检测一个数组里有没有重复的值
    PHP serialize 和 JSON 解析与区别
    php 单文件上传
    php 数组 类对象 值传递 引用传递 区别
    六. 网络编程(解决黏包TCP)
    五. 网络编程(UDP 不黏包)
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5744460.html
Copyright © 2011-2022 走看看