给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水
1.你不能倾斜容器
2.当n小于2时,视为不能形成容器,请返回0
3.数据保证能容纳最多的水不会超过整形范围,即不会超过231-1
数据范围:
如输入的height为[1,7,3,2,4,5,8,2,7],那么如下图:
[1,7,3,2,4,5,8,2,7]
49
[2,2]
2
[5,4,3,2,1,5]
25
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型vector
* @return int整型
*/
struct TokaiTeio {
int x, i;
bool operator < (const TokaiTeio& b) const {
return x < b.x;
}
TokaiTeio() : x(0), i(0) {};
};
bool cmp(TokaiTeio A, TokaiTeio B) {
return A.x < B.x;
}
int f[200005][22],dp[200005][22];
int a[200005],b[200005];
//区间最大
void work(int n) {
for (int i = 1; i <= n; i++) f[i][0] = a[i];
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
int RMQ(int l, int r) {
int k = 0;
while ((1 << (k + 1)) <= r - l + 1)
k++;
return max(f[l][k], f[r - (1 << k) + 1][k]);
}
//区间最小
void work2(int n) {
for (int i = 1; i <= n; i++) dp[i][0] = b[i];
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
int RMQ2(int l, int r) {
int k = 0;
while ((1 << (k + 1)) <= r - l + 1)
k++;
return min(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int maxArea(vector<int>& height) {
// write code here
if (height.size() < 2) return 0;
int cnt = 0;
int ans = 0;
TokaiTeio z[height.size() + 3];
for (auto it : height) {
z[++cnt].x = it;
z[cnt].i = cnt;
}
sort(z + 1, z + cnt + 1);
for(int i = 1; i <= cnt; i ++ ) a[i] = z[i].i;
for(int i = 1; i <= cnt; i ++ ) b[i] = z[i].i;
work(cnt);
work2(cnt);
int l = 1;
for(int i = 1; i <= cnt; i ++ )
{
if(z[i].x != z[i - 1].x) l = i;
ans = max({ans,(abs(RMQ(l,cnt) - z[i].i)) * z[i].x,(abs(RMQ2(l,cnt) - z[i].i)) * z[i].x});
}
return ans;
}
}; #include <algorithm>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型vector
* @return int整型
*/
int maxArea(vector<int>& height) {
// write code here
int left=0, right=height.size()-1, res=0;
if(right<1) return res;
while (left<right) {
int contains = (right-left)*min(height[left], height[right]);
if(contains>res){
res = contains;
}
if(height[left]>height[right]){
int v = height[right];
right--;
while (right>left&&height[right]<=v) {
right--;
}
}else{
int v = height[left];
left++;
while (right>left&&height[left]<=v) { //加速,如果换掉的边界比原来矮,则必不可能盛放更多的水,继续换
left++;
}
}
}
return res;
}
}; import java.util.*;
public class Solution {
public int maxArea (int[] height) {
// write code here
int ans = 0;
int l = 0, r = height.length - 1;
while (l < r) {
ans = Math.max(ans, Math.min(height[l],height[r]) * (r - l));//计算盛水选择短板
if (height[l] < height[r]) ++l;
else --r; //移动短板
}
return ans;
}
} class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型vector
* @return int整型
*/
int maxArea(vector<int>& height) {
// 时间复杂度O(N),空间复杂度O(1)
if (height.size() < 2) return 0;
int left = 0, right = height.size() - 1, res = 0, tmp;
while (left < right) {
tmp = min(height[left], height[right]) * (right - left);
res = res > tmp ? res : tmp;
if (height[left] < height[right]) ++left;
else --right;
}
return res;
}
}; class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型vector
* @return int整型
*/
int maxArea(vector<int>& height) {
// write code here
int n = height.size();
if (n < 2) {
return 0;
}
int ans = 0;
int i = 0, j = n-1;
while (i < j) {
ans = max(ans, min(height[i], height[j]) * (j - i));
if (height[i] < height[j]) {
i++;
}else {
j--;
}
}
return ans;
}
}; import java.util.*;
// @@@ 盛水: 类似接雨水
// 双指针i,j初始两端,每次移动小的那端,遇到更高的更新两端大小关系 & 面积
// 直到i,j相遇
public class Solution {
public int maxArea (int[] height) {
if (height.length == 0) return 0;
int res = 0, i = 0, j = height.length - 1, left = height[i], right = height[j];
while (i <= j) {
res = Math.max(res, Math.min(left, right) * (j - i)); // 计算面积
// System.out.printf("i=%d j=%d %d %d res=%d\n", i, j, height[i], height[j], res);
// 左端更矮, 移动i
if (left <= right) {
while (i <= j && height[i] <= left) { // 更低高度的,面积肯定更小,略过
i++;
}
if (i <= j) left = height[i]; // 遇到更高的,更新左端高
}
// 右端更矮, 移动j
else {
while (i <= j && height[j] <= right) {
j--;
}
if (i <= j) right = height[j];
}
}
return res;
}
} class Solution: def maxArea(self , height: List[int]) -> int: # write code here '''超时了''' # if len(height) < 2: # return 0 # left = 0 # res = 0 # while left < len(height) - 1: # for right in range(left + 1, len(height)): # mianji = min(height[left], height[right]) * (right - left) # res = max(res,mianji) # left = left + 1 # return res '''双指针''' left = 0 right = len(height) - 1 res = 0 while left < right: mianji = min(height[left], height[right])*(right - left) res = max(res, mianji) if height[left] < height[right]: left = left + 1 else: right = right - 1 return res
public class Solution {
public int maxArea (int[] height) {
int max = 0;
int left=0;
int right=height.length-1;
while(left<right){
max=Math.max(max,(right-left)*Math.min(height[left],height[right]));
if(height[left]<height[right]) left++;
else right--;
}
return max;
}
}
int maxArea(int* height, int heightLen ) {
if (heightLen < 2) return 0; //小于2不能形成容器
int left = 0;
int right = heightLen - 1;
int max = 0; //存放最终的最大容积
int maxTemp = 0; //存放临时容积
while (left < right)
{
maxTemp = height[left] > height[right] ? \
height[right] * (right- left) \
:height[left] * (right- left) ; //计算每次容积大小
if (maxTemp > max) max = maxTemp;
//贪心算法,移动较短边
if (height[left] > height[right]) --right;
else ++left;
}
return max;
} public int maxArea(int[] height) {
// write code here
if (height.length < 2)
return 0;
int maxArea = 0;
int left = 0, right = height.length - 1;
while (left < right) {
int currArea = (right - left) * Math.min(height[left], height[right]);
maxArea = Math.max(maxArea, currArea);
if (height[left] < height[right])
left++;
else
right--;
}
return maxArea;
} #include <type_traits>
class Solution {
public:
/**
夹逼定理
*/
int maxArea(vector<int>& height) {
int ans = 0;
int temp = 0;
int head = 0, tail = height.size() - 1;
while (head < tail) {
temp = min(height[head], height[tail]) * (tail - head);
ans = max(ans, temp);
if (height[head] > height[tail]) {
tail--;
} else {
head++;
}
}
return ans;
}
};