【LeetCode】Container with Most Water
2017-05-09 14:12
387 查看
算法小白,最近刷LeetCode。希望能够结合自己的思考和别人优秀的代码,对题目和解法进行更加清晰详细的解释,供大家参考^_^
Note: You may not slant the container and n is at least 2.
题目的大意是说,给定非负整数a1,a2, … , an,点 (i, ai) 和点 (i, 0) 形成一条垂直于x轴的线段,从这n条垂直线段中任选两条,与x轴形成一个容器,求容器所能盛水的最大值。
显然,盛水量取决于最矮的那个高度,所以基本计算公式为:
res = max( (j - i) * min( a[i], a[j] ) )
遍历所有的i和j,取最大值即可,显然这样是一个O(n^2)的算法,是会超时的。
先来考虑底长为n-1的容器,其最大盛水量为(n-1)*min(a
, a[1]),接下来考虑底长为n-2的容器,此时,由于底变小,高度必须增加,才能盛下更多水,因此只能保留较高的边,试图从另一条边开始寻找比它自身更高的边,只有这样,才能保证容器盛水量的扩大。
按照上面的思路,有以下代码:
上述代码是一个时间复杂度为O(n)的算法,提交后却发现运行时间仅仅击败了20%的方案,看了别人的代码发现,他们是这么写的:
上述代码的运行时间击败了94%的其他方案。仔细思考了一下,当数据呈递增方式排列时,第一份代码的确会进行很多额外的操作,造成运行时间的增长。
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 and n is at least 2.
题目的大意是说,给定非负整数a1,a2, … , an,点 (i, ai) 和点 (i, 0) 形成一条垂直于x轴的线段,从这n条垂直线段中任选两条,与x轴形成一个容器,求容器所能盛水的最大值。
显然,盛水量取决于最矮的那个高度,所以基本计算公式为:
res = max( (j - i) * min( a[i], a[j] ) )
遍历所有的i和j,取最大值即可,显然这样是一个O(n^2)的算法,是会超时的。
先来考虑底长为n-1的容器,其最大盛水量为(n-1)*min(a
, a[1]),接下来考虑底长为n-2的容器,此时,由于底变小,高度必须增加,才能盛下更多水,因此只能保留较高的边,试图从另一条边开始寻找比它自身更高的边,只有这样,才能保证容器盛水量的扩大。
按照上面的思路,有以下代码:
class Solution { public: int maxArea(vector<int>& height) { int res = 0; int left = 0, right = height.size() - 1; //两个指针分别指向左边界和右边界 while (left < right){ res = max(res, (right - left) * min(height[left], height[right])); //计算并更新最大盛水量 // 如果右边界更高,则保留右边界,从左边界开始查找比其更高的新边界,并进行更新 if (height[left] <= height[right]){ int i = left + 1; while (height[i] <= height[left] && i < right) ++i; // 忽略掉比当前左边界还要矮的,因为它只能让盛水量变小 left = i; } else { // 同理,从右边界向左查找 int i = right - 1; while (height[i] <= height[right] && i > left) --i; right = i; } } return res; } };
上述代码是一个时间复杂度为O(n)的算法,提交后却发现运行时间仅仅击败了20%的方案,看了别人的代码发现,他们是这么写的:
class Solution { public: int maxArea(vector<int>& height) { int res = 0; int left = 0, right = height.size() - 1; while (left < right){ res = max(res, (right - left) * min(height[left], height[right])); if (height[left] <= height[right]) ++left; else --right; } return res; } };
上述代码的运行时间击败了94%的其他方案。仔细思考了一下,当数据呈递增方式排列时,第一份代码的确会进行很多额外的操作,造成运行时间的增长。
相关文章推荐
- leetcode—Container With Most Water
- Leetcode Container With Most Water
- Leetcode 11 Container With Most Water
- Leetcode Container With Most Water
- leetcode Container With Most Water
- [leetcode javascript解题]Container With Most Water
- leetcode 11 Container With Most Water
- [LeetCode]Container With Most Water、Trapping Rain Water
- leetcode Container With Most Water
- leetcode-java.T011_ContainerWithMostWater 找两条竖线然后这两条线以及X轴构成的容器能容纳最多的水
- [LeetCode-Algorithms-11] "Container With Most Water" (2017.10.2-WEEK5)
- leetcode - Container With Most Water
- LeetCode11:Container With Most Water
- leetcode 11 Container with Most Water
- [Leetcode] Container With Most Water
- LeetCode:Container With Most Water
- Container With Most Water——LeetCode
- leetcode Container With Most Water
- LeetCode 011 Container With Most Water
- LeetCode-11-Container-With-Most-Water 贪心