给定一个数组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; } };
int maxArea(int* height, int heightLen ) { // write code here int res,i,*j,*heightMax,*heightLeft,*heightRight; if(heightLen<2) return 0; heightMax = height; for(i=0;i<heightLen;i++) { if(*heightMax<height[i]) heightMax=&height[i]; } heightLeft = heightMax; heightRight = heightMax; res = 0; for(i=heightMax-height,j=heightMax;i>0;i--) { long long volume; j--; volume = (*j) * (heightMax-j); if(res<volume) { res = volume; heightLeft = j; } } res = 0; for(i=heightMax-height,j=heightMax;i<heightLen-1;i++) { long long volume; j++; volume = (*j) * (j-heightMax); if(res<volume) { res = volume; heightRight = j; } } res = 0; for(i=heightRight-height,j=heightRight;i>0;i--) { long long volume; j--; volume = (*j>*heightRight?*heightRight:*j) * (heightRight-j); if(res<volume) { res = volume; heightLeft = j; } } res = 0; for(i=heightLeft-height,j=heightLeft;i<heightLen-1;i++) { long long volume; j++; volume = (*j>*heightLeft?*heightLeft:*j) * (j-heightLeft); if(res<volume) { res = volume; heightRight = j; } } res = (*heightLeft) * (heightMax-heightLeft); res = (*heightRight) * (heightRight-heightMax) > res ? (*heightRight) * (heightRight-heightMax) : res; res = (*heightLeft>*heightRight ? *heightRight: *heightLeft) * (heightRight-heightLeft) > res ? (*heightLeft>*heightRight ? *heightRight: *heightLeft) * (heightRight-heightLeft) : res; return res; }
package main /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param height int整型一维数组 * @return int整型 */ func maxArea( height []int ) int { // write code here if len(height) < 1 {return 0} res, l, r := 0, 0, len(height) - 1 for l < r { res = getMax(res, getMin(height[l], height[r]) * (r - l)) if height[l] <= height[r] { l ++ } else { r -- } } return res } func getMin(l, r int) int { if l <= r { return l } return r } func getMax(res, tmp int) int { if res < tmp { return tmp } return res }