您的位置:首页 > 大数据 > 人工智能

11. Container With Most Water \ 16. 3Sum Closest \ 15. 3Sum

2017-01-20 00:46 441 查看

11. Container With Most Water

这道题先用暴力破解,超时:这种O(n^2)的复杂度一般都是扑街的。

public  int maxArea1(int[] height){
if ( (height == null) || (height.length <= 1) )
return 0 ;

int result = 0 ;
ArrayList<Integer> seq = new ArrayList<Integer>();
seq.add(new Integer(0));
for (int i = 1 ; i < height.length; i++){
for ( Integer idx : seq ){
int ht = height[i] > height[idx.intValue()] ? height[idx.intValue()] : height[i] ;
int area = (i - idx.intValue()) * ht ;
if ( area > result ) result = area ;
}
int lastIdx = seq.get(seq.size() - 1).intValue();
if ( height[i] > height[lastIdx]){
seq.add(new Integer(i)) ;
}
}
return result ;
}


然后就有了以下解法:就是从左边和右边个一个数往里面缩,但是怎么移动这些数字呢?假设返回的不是最优解,那么在计算的过程中一定会发生的就是会经过左边或者右边的最优解而不会同时经过两个。假设经过左边的最优解,右边的还没有移动到,如果移动左边并没有遇到右边的最优解,说明右边有比左边更大的数,那么它的面积已经大于了所谓的最优解,那么与之前的假设相冲突。还有一个解释就是左右两边的节点,左边已经更小的话,那么这个左边节点与右边节点之间的节点结合也不会比目前的大,因为受制于左边节点参考

这种算法我记得没错的话就是饥饿算法。

class Solution {
public:
int maxArea(vector<int>& height) {
int height_len = height.size();
int area_max = 0;
int llow = 0, rhigh = height_len - 1;

while(llow < rhigh)
{
int smaller = (height[llow] > height[rhigh])?height[rhigh]:height[llow];
int area_tmp = (rhigh - llow)*smaller;

if(area_tmp > area_max)
area_max = area_tmp;
if(height[llow] > height[rhigh])
rhigh--;
else
llow++;
}

return area_max;
}
};


以上的算法还可以简写成:

int maxArea(vector<int>& height) {
int water = 0;
int i = 0, j = height.size() - 1;
while (i < j) {
int h = min(height[i], height[j]);
water = max(water, (j - i) * h);
while (height[i] <= h && i < j) i++;
while (height[j] <= h && i < j) j--;
}
return water;
}


我觉得上面这个算法太好了,但是我觉得通用性好像没有那么强,感觉要靠猜结果来得到。以下算法我觉得更有通用性。这个解释应用了动态规划来解释,感觉清楚很多参考

那么代码可以写成:

class Solution {
public:
int maxArea(vector<int>& height) {
int height_len = height.size();
int area_max = 0;
int llow = 0, rhigh = height_len - 1;
height_len--;

for(int i = 0; i < height_len; i++){
int smaller = (height[llow] > height[rhigh])?height[rhigh]:height[llow];
int area_tmp = (rhigh - llow)*smaller;

if(area_tmp > area_max)
area_max = area_tmp;
if(height[llow] > height[rhigh])
rhigh--;
else
llow++;
}

return area_max;
}
};


16. 3Sum Closest

这道题的做法和上面其实是一样的思路,只是因为这里是3维的,就需要进行一个固定,另外两个变量进行动规处理。

class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int nums_len = nums.size();
int sum_tmp;
int result = INT_MAX;
int ind_1st = 0, ind_2nd = 1, ind_3rd = nums_len - 1;
int bound = INT_MAX;

sort(nums.begin(), nums.end());

while(ind_1st < ind_2nd && ind_2nd < ind_3rd) {
int stt = ind_2nd;
int endf = ind_3rd;
while(stt < endf){
sum_tmp = nums[ind_1st] + nums[stt] + nums[endf];
if(sum_tmp >target)
endf--;
else
stt++;

int bound_tmp = abs(sum_tmp - target);
if(bound_tmp < bound){
bound = bound_tmp;
if(!bound)
return sum_tmp;
else
result =sum_tmp;
}
}
ind_1st++;
ind_2nd = ind_1st + 1;
}

return result;
}
};


15. 3 sum

class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int nums_len = nums.size();
int ind1 = 0, ind2 = 1, ind3 = nums_len - 1;
vector<vector<int> >result;
nums_len--;

sort(nums.begin(), nums.end());

while(ind1 < ind2 && ind2 < ind3)
{
int stt = ind1 + 1;
int endf = ind3;
while(stt < endf)
{
vector<int> tmp;
int sum_tmp = nums[ind1] + nums[stt] + nums[endf];

if(sum_tmp == 0)
{
tmp.push_back(nums[ind1]);
tmp.push_back(nums[stt]);
tmp.push_back(nums[endf]);
result.push_back(tmp);

while(endf > stt && nums[endf - 1] == nums[endf]){
endf--;
}
while(stt < endf && nums[stt] == nums[stt + 1]){
stt++;
}
stt++;
}
else if(sum_tmp > 0)
{
endf--;
}
else
{
stt++;
}
}

while(ind1 < ind3 && nums[ind1] == nums[ind1 + 1])
{
ind1++;
}
ind1++;
ind2 = ind1 + 1;
}

return result;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息