• 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 };
  • 相关阅读:
    (2)链表有哪几种分类——4
    (1)有哪几种表的实现方式——4
    链表基本操作
    多窗口
    UI线程和work线程
    模板
    (二)tensorflow-gpu2.0之自动导数
    (一)tensorflow-gpu2.0学习笔记之开篇(cpu和gpu计算速度比较)
    高阶函数及map、reduce、filter、lambda、sorted等函数的应用
    迭代器
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5744460.html
Copyright © 2020-2023  润新知