今天在leetcode上做了一天,随便找了一些题大概做了10几个,感觉面试题真的很能体现个人能力啊。
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.
题目意思还是比较好懂的,O(n*n)的大家都能够想到了,很明显这肯定不是最好的答案。
我们定义i j为最大的容器区间。
我的第一个想法是简单剪枝,当我们遍历j的时候,为了求i,从0开始遍历遇到高度
height[i]>=height[j],时停止。因为最大容量计算公式为min(height[i],height[j])*(j-i)。这种想法虽然能减少一定的查找,但是时间复杂度不会变。最坏情况:递增的时候。
后来一想这个其实就是找合适区间,题目让我们想的合适区间应该是越大越好。因为要求容量最大。于是先把这个区间定义为最大 i=0,j=n-1; 如果这个最大的区间容量不是最大,那么这个区间子区间是相对较小的,我们只要找比区间边缘高度高的即可。
也就是说:当左边小于右边的时候,从左边开始找比左边缘更大的。
当右边小于左边,更新右边边缘,即找比右边缘更大的。
算法时间复杂度O(n);
class Solution {
public:
int maxArea(vector<int> &height) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(height.size()<2)
return 0;
int mmax=0;
int l=0;
int r=height.size()-1;
while(l<r)
{
mmax=max(mmax,min(height[l],height[r])*(r-l));
if(height[l]<=height[r])
l++;
else
r--;
}
return mmax;
}
};
class Solution { public: int maxArea(vector<int> &height) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. if(height.size()<2) return 0; int mmax=0; int l=0; int r=height.size()-1; while(l<r) { mmax=max(mmax,min(height[l],height[r])*(r-l)); if(height[l]<=height[r]) { int t=l; while(t<r &&height[t]<=height[l]) t++; l=t; } else { int t=r; while(l<t &&height[t]<=height[r]) t--; r=t; } } return mmax; } };