力扣11.盛最多水的容器

题目: 传送门
题意: 大家都知道木桶的原理,木桶盛水在于它最短的那个木板,这个题是给你一系列木板,已经排好,现在问你,在两个木板之间倒水,选择哪两个木板可以使盛水最多,木板之间的距离已经确定。让我们先看一个样例:
在这里插入图片描述
在最开始的时候我没有思路,之间想着暴力,但是这个数组的范围特别的大,如果暴力就需要两层循环,时间复杂度就不能够满足。我们知道如何判断这两个木板之间盛水最多,就是让两个木板之间的距离乘以两个木板中短的那一个,但是又不能遍历所有情况来判断,有没有什么思路可以使在判断下一种情况时能够找到最优情况,从而来使我们减少判断次数。
最后,我看了官方给的题解,官方思路是使用双指针,分别指向两个边界,然后判断两个指针指向木板的长短,将短的移出,继续判断,这样遍历的结果就是只便利了一遍数组,这时的时间复杂度就是O(n),这样的方法的确很好。但是,为什么这种方法得到的就是最优结果呢?并且是否考虑了所有情况呢?
让我们通过样例1看一下:

1	8	6	2	5	4	8	3	7

我们用l代表左边的指针,r代表右边的指针,w代表盛水的量。
最开始: l=1,r=7,w=(8-0)*1=8;
1<=7,l++: l=8,r=7,w=(8-1)*7=49;
8>7,r–: l=8,r=3,w=(7-1)*3=18;
8>3,r–: l=8,r=8,w=(6-1)*8=40;

这就是它的过程,我们知道影响盛水量的影响因素主要有木板长度和距离两个因素,因此,把指针指向两端的边界这个时候就保证了其中一个因素最大,只需要考虑木板长度的这一因素。为什么移动短的木板呢?我们知道盛水考虑的是边界两端短的那一个,如果我们把长的移出,那么对新的区间就有可能产生影响,但是移动短的,我们就能保证新的区间这时候是最优。
代码:

#include<iostream>
#include<vector>
using namespace std;

class Solution {
    
    
public:
	int maxArea(vector<int>& height);
};

int Solution::maxArea(vector<int>& height) {
    
    
	int l = 0, r = height.size() - 1;
	int Max = 0;
	while (l <= r) {
    
    
		Max = max(Max, (r - l) * min(height[l], height[r]));
		if (height[l] <= height[r]) {
    
    
			l++;
		}
		else {
    
    
			r--;
		}
	}
	return Max;
}

int main() {
    
    
	vector<int>height;
	int number;
	while (1) {
    
    
		cin >> number;
		height.push_back(number);
		if (cin.get() == '\n')
			break;
	}
	Solution s;
	cout << s.maxArea(height) << endl;
	return 0;
}

ヾ(◍°∇°◍)ノ゙

猜你喜欢

转载自blog.csdn.net/qq_43840681/article/details/117986152