https://leetcode.com/problems/trapping-rain-water/
题目描述
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水。
具体请参考样例解释
输入描述:
第一行一个整数N,表示数组长度。 接下来一行N个数表示数组内的数。
输出描述:
输出一个整数表示能装多少水。
示例1
输入
6 3 1 2 5 2 4
输出
5
//暴力解法:O(n^2) 每次寻找该点左边最大值和该点右边最大值,res+=min(l_max,r_max)-data[i]
//运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
//case通过率为20.00%
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> data(n);
for(int i=0;i<n;i++){
cin>>data[i];
}
long long res=0;
for(int i=1;i<n-1;i++){
int l_max=0;
int r_max=0;
for(int j=0;j<=i;j++){
l_max=max(l_max,data[i]);
}
for(int j=i;j<n;j++){
r_max=max(r_max,data[i]);
}
res+=min(l_max,r_max)-data[i];
}
cout<<res<<endl;
return 0;
}
Algorithm
- Initialize left pointer to 0 and right pointer to size-1
- While left<right, do:
- If height[left] is smaller than height[right]
- If height[left]≥left_max, update left_max
- Else add left_max−height[left] to ans
- Add 1 to left.
- Else
- If height[right]≥right_max, update right_max
- Else add right_max−height[right] to ans
- Subtract 1 from right.
- If height[left] is smaller than height[right]
//方法2:使用双指针技术 O(n)
//不断的让左边data[left]或者右边data[right]大的当墙,该位置增加的水量取决于小端
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> data(n);
for(int i=0;i<n;i++){
cin>>data[i];
}
long long res=0;
int left=0,right=n-1;
int l_max=0,r_max=0;
while(left<right){
if(data[left]<data[right]){ //如果data[left]<data[right],可以保证l_max<data[right]
l_max=max(l_max,data[left]);
res+=l_max-data[left];
left++;
}else{
r_max=max(r_max,data[right]);
res+=r_max-data[right];
right--;
}
}
cout<<res<<endl;
return 0;
}
//方法2使用双指针技术 O(n)
//另一种实现方式:单纯使用l_max,r_max当墙,计算中间每一个位置可以增加的水量
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> data(n);
for(int i=0;i<n;i++){
cin>>data[i];
}
long long res=0;
int left=1,right=n-2;
int l_max=data[0],r_max=data[n-1];
while(left<=right){
if(l_max<r_max){
l_max=max(l_max,data[left]);
res+=l_max-data[left];
left++;
}else{
r_max=max(r_max,data[right]);
res+=r_max-data[right];
right--;
}
}
cout<<res<<endl;
return 0;
}