
双指针 :
1.对于两条确定的边界,l和r,取中间的线m与r组成容器,如果m的高度>l的高度,那么整个容器的长度会减小,如果低于l的高度,那么不仅高度可能会减小,长度也一定会减小;
2.取l=0,r=n-1,循环遍历答案即可;
- class Solution {
- public:
- int maxArea(vector<int>& height) {
- int n = height.size();
- int i=0,j=n-1,ans=0;
- while(i < j){
- ans = height[i] < height[j] ?
- max(ans, (j - i) * height[i++]):
- max(ans, (j - i) * height[j--]);
- }
- return ans;
- }
- };
- class Solution:
- def maxArea(self, height: List[int]) -> int:
- ans = 0
- l = 0
- r = len(height)-1
- while l
- s = (r-l)*min(height[l],height[r])
- ans = max(ans,s)
- if height[l] < height[r]:
- l += 1
- else :
- r -= 1
- return ans
接雨水
链接 :
https://leetcode.cn/problems/trapping-rain-water/
思路 :
假设每个位置都是一个宽度为一的桶;
对于每个位置能够存多少水,取决于左边和右边的最大高度;
法一 :
用两个数组来表示 前缀 和 后缀的最大值;
详见代码一
时间复杂度 : O(n)
空间复杂度 : O(n)
法二 :
双指针 :
取l=0,r=n-1;
一边遍历一边更新前缀的最大值pre_max 和 后缀的最大值suf_max!
时间复杂度 : O(n)
空间复杂度 : O(1)
详见代码二
代码 :
代码一 :
python :
- class Solution:
- def trap(self, height: List[int]) -> int:
- n = len(height)
- # 前缀最大值数组
- fs = [0] * n
- fs[0] = height[0]
- for i in range(1,n):
- fs[i] = max(fs[i-1],height[i])
-
- # 后缀和最大值数组
- es = [0] * n
- es[-1] = height[n-1]
- for i in range(n-2,-1,-1):
- es[i] = max(es[i+1],height[i])
-
- ans = 0
- for h , f , e in zip(height,fs,es):
- ans += min(f,e)-h
-
- return ans
代码二 :
python :
- class Solution:
- def trap(self, height: List[int]) -> int:
- n = len(height)
- l = 0
- r = n - 1
- ans = 0
- pre_max = 0
- suf_max = 0
-
- while l<=r:
- pre_max = max(pre_max,height[l])
- suf_max = max(suf_max,height[r])
- if pre_max < suf_max :
- ans += pre_max-height[l]
- l += 1
- else :
- ans += suf_max - height[r]
- r -= 1
-
- return ans
c++ :
- class Solution {
- public:
- int trap(vector<int>& a) {
-
- int len = a.size();
- int lmax=a[0],rmax=a[len-1];
- int l=1,r=len-2;
- int ans=0;
- while(l<=r){
- if(lmax < rmax){
- ans += max(min(lmax,rmax)-a[l],0);
- lmax = max(lmax,a[l]);
- l++;
- }
- else{
- ans += max(min(lmax,rmax)-a[r],0);
- rmax = max(rmax,a[r]);
- r--;
- }
- }
- return ans;
- }
- };