炎炎夏日,还是呆在空调房里切切题吧。

Container With Most Water,题意其实有点噱头,简化下就是,给一个数组,恩,就叫 height 吧,从中任选两项 i 和 j(i <= j),使得 Math.min(height[i], height[j]) * (j - i) 最大化,求解这个最大值。

O(n^2)

O(n^2) 复杂度的解法非常容易想到,直接两两枚举。

var maxArea = function(height) {
  var len = height.length;
  var maxn = 0;

  for (var i = 0; i < len; i++)
    for (var j = i + 1; j < len; j++)
      maxn = Math.max(maxn, Math.min(height[i], height[j]) * (j - i));

  return maxn;
};

提交,TLE,看了下数据,数组长度 1w,复杂度直接飙到亿级,不 TLE 才怪了。

O(nlogn)

我们假设数组为 [a1, a2, ..., an],我们实际需要求得的其实是一个子数组。假设这个子数组的最后一个元素是 a5,同时我们规定该子数组最后一个元素不大于第一个元素,那么实际我们需要求的是 a1, a2, a3, a4 中哪个元素比 a5 大(或者相同),并且这个元素越前面越好。

这样,我们可以遍历每个元素,将这个元素确定为子数组的最后一个元素,同时去求前面已经被遍历过的元素中,大于等于该元素并且最左的元素。对于求这个最左元素,我们可以维护一个单调递增的数组,用二分去解。

二分需要求解一个递增序列中,刚好大于等于指定元素的位置,这个 case 没有出现在 二分查找大集合(妈妈再也不用担心我的二分查找了),我们可以稍微变个形。

// 求解 a 数组中刚好大于等于 target 的位置
// 如果都小于 target 则返回 a.length
function binarySearch(a, target) {
  target += 1;
  var start = 0
    , end = a.length - 1;

  while(start <= end) {
    var mid = ~~((start + end) >> 1);
    if (a[mid] >= target)
      end = mid - 1;
    else
      start = mid + 1;
  }

  if (a[start - 1] === target - 1)
    start -= 1;
  return start;
}

还需要注意的一点是,必须正反来两次,因为我们假设子数组的最后一个元素小于等于首元素,还需要考虑另一种情况,即子数组首元素小于等于最后一个元素。

其他部分问题不大,具体代码可以参考 https://github.com/hanzichi/leetcode/blob/master/Algorithms/Container%20With%20Most%20Water/O(nlogn).js

提交,AC,击败 4% ... 势必还有更优的解法,而且根据我的经验,如果这是标程正解的话,这道题的难度应该是 Hard 而不是 Medium 了。

O(n)

正解的复杂度应该是 O(n) 的。

我们可以举个简单的例子,假设数组是 [2, 3, 4, 5, 4, 3],那么最长的子数组一定只有一个,即取全部元素,这样能装的水的数量是 2 * 5 。接下去我们的子元素,长度一定是会变小的,有两种情况,为 [2, 3, 4, 5, 4][3, 4, 5, 4, 3]。我们来看 [2, 3, 4, 5, 4],这种情况下,显然比取全部元素求得的结果 10 要小,为什么这么说?因为两者的基准都是按 2 来算的,但是取全部元素长度大。

似乎有点眉目了,再来看 [2, 3, 4, 5, 4, 3] 这个原始的数组,从中找出一个子数组,如果以 2 为子数组最左的元素,那么这个子数组求解的值(即装水的量),不可能比 [2, 3, 4, 5, 4, 3] 这个原始数组求到的 10 要大了,有木有?!因为该子数组装水的基准,是不可能比 2 大了的。

这样,我们似乎可以用一点点贪心去解这道题,一步步缩小子数组的大小。

while (start <= end) {
  maxn = Math.max(maxn, Math.min(height[end], height[start]) * (end - start));

  if (height[end] < height[start])
    end --;
  else
    start ++;
}

完整代码可以参考 https://github.com/hanzichi/leetcode/blob/master/Algorithms/Container%20With%20Most%20Water/O(n).js

如何装最多的水? — leetcode 11. Container With Most Water的更多相关文章

  1. [LeetCode] 11. Container With Most Water My Submissions Question 解题思路

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...

  2. leetcode 11. Container With Most Water 、42. Trapping Rain Water 、238. Product of Array Except Self 、407. Trapping Rain Water II

    11. Container With Most Water https://www.cnblogs.com/grandyang/p/4455109.html 用双指针向中间滑动,较小的高度就作为当前情 ...

  3. Leetcode 11. Container With Most Water(逼近法)

    11. Container With Most Water Medium Given n non-negative integers a1, a2, ..., an , where each repr ...

  4. [LeetCode] 11. Container With Most Water 装最多水的容器

    Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). ...

  5. 蜗牛慢慢爬 LeetCode 11. Container With Most Water [Difficulty: Medium]

    题目 Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai ...

  6. LeetCode 11. [👁] Container With Most Water & two pointers

    盛最多水的容器 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找 ...

  7. LeetCode 11. Container With Most Water (装最多水的容器)

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...

  8. [leetcode]11. Container With Most Water存水最多的容器

    Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). ...

  9. [LeetCode]11. Container With Most Water 盛最多水的容器

    Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). ...

随机推荐

  1. Ionic2系列-将beta升级到RC1

    国庆节前Ionic2发布了RC0版本,已经接近正式版了,前不久Angular2和TypeScript2也已经发布了正式版.详情请参考官方博客: http://blog.ionic.io/announc ...

  2. CentOS下安装hadoop

    CentOS下安装hadoop 用户配置 添加用户 adduser hadoop passwd hadoop 权限配置 chmod u+w /etc/sudoers vi /etc/sudoers 在 ...

  3. JavaScript结构三层——思想快速介绍

    本文版权归博客园和作者吴双本人所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/,我是博客园蜗牛,我们共同进步. 今天讨论的是什么 如果你的工作中需要写JavaS ...

  4. 【C#】给无窗口的进程发送消息

    注:本文适用.net2.0+的winform程序 一个winform程序,我希望它不能多开(但是如何防多开不是本文要讲的),那么在用户启动第二个实例的时候,作为第二个实例来说,大概可以有这么几种做法: ...

  5. 来玩Play框架05 数据库

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 数据库是整个站点的数据储藏室.用户提交的数据可以存储在数据库中,以便未来使用.Pl ...

  6. [转] 评 WOW技能天赋设计

    本文转至:http://bbs.chinaunix.net/thread-1692302-8-1.html(只作转载, 不代表本站和博主同意文中观点或证实文中信息)再比如,传说中的面向对象本该大显神威 ...

  7. JavaScript的“原型甘露”

    今天跟朋友讨论JS的面向对象编程问题,想起了原来曾经看过一篇文章,但是看过很久想不起来了,用了很多关键词,终于用“悟透JavaScript  面向对象”这两个关键词找到了“原文”,原文地址:http: ...

  8. jQuery与ajax 基础运用

    jQuery是一个轻量级js框架,使用方便快捷,更是封装ajax处理方法,如$.load() $.get() $.post() 等 但最常用的方法还是$.ajax() 一.一般的格式为 $.ajax( ...

  9. Position属性四个值:static、fixed、relative、absolute的区别和用法

    1.static(静态定位):默认值.没有定位,元素出现在正常的文档流中(如果设置 top, bottom, left, right, z-index这些属性就不起做作了). 2.relative(相 ...

  10. ES6之字符串扩展方法(常用)

    es6这个String对象倒是扩展了不少方法,但是很多都是跟字符编码相关,个人选了几个感觉比较常用的方法: includes 搜索字符的神器 还记得我们之前如何判断某个字符串对象是否包含特地字符的吗? ...