力扣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;
}

ヾ(◍°∇°◍)ノ゙

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赟家小菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值