炎炎夏日,仍是呆在空调房里切切题吧。javascript
Container With Most Water,题意其实有点噱头,简化下就是,给一个数组,恩,就叫 height
吧,从中任选两项 i 和 j(i <= j),使得 Math.min(height[i], height[j]) * (j - i)
最大化,求解这个最大值。html
O(n^2) 复杂度的解法很是容易想到,直接两两枚举。java
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 才怪了。git
咱们假设数组为 [a1, a2, ..., an],咱们实际须要求得的实际上是一个子数组。假设这个子数组的最后一个元素是 a5,同时咱们规定该子数组最后一个元素不大于第一个元素,那么实际咱们须要求的是 a1, a2, a3, a4 中哪一个元素比 a5 大(或者相同),而且这个元素越前面越好。github
这样,咱们能够遍历每一个元素,将这个元素肯定为子数组的最后一个元素,同时去求前面已经被遍历过的元素中,大于等于该元素而且最左的元素。对于求这个最左元素,咱们能够维护一个单调递增的数组,用二分去解。数组
二分须要求解一个递增序列中,恰好大于等于指定元素的位置,这个 case 没有出如今 二分查找大集合(妈妈不再用担忧个人二分查找了),咱们能够稍微变个形。code
// 求解 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; }
还须要注意的一点是,必须正反来两次,由于咱们假设子数组的最后一个元素小于等于首元素,还须要考虑另外一种状况,即子数组首元素小于等于最后一个元素。htm
其余部分问题不大,具体代码能够参考 https://github.com/hanzichi/leetcode/blob/master/Algorithms/Container%20With%20Most%20Water/O(nlogn).jsblog
提交,AC,击败 4% ... 势必还有更优的解法,并且根据个人经验,若是这是标程正解的话,这道题的难度应该是 Hard 而不是 Medium 了。ip
正解的复杂度应该是 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