class Solution {
public int trap(int[] height) {
int sum = 0;
int maxId = 0;
for (int i = 1; i < height.length; i++)
if (height[i] > height[maxId]) maxId = i;
int lmax = 0;
for (int i = 0; i < maxId; i++) {
if (lmax <= height[i]) lmax = height[i];
else sum += (lmax - height[i]);
}
int rmax = 0;
for (int i = height.length - 1; i > maxId; i--) {
if (rmax <= height[i]) rmax = height[i];
else sum += (rmax - height[i]);
}
return sum;
}
}
public class Trap {
public static void main(String[] args) {
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
int trap = trap3(height);
System.out.println(trap);
}
public static int trap1(int[] height) {
int n = height.length;
int res = 0;
for(int i = 1;i < n-1;i++){
int l_max = 0;
int r_max = 0;
for(int j = i;j < n;j++){
r_max = Math.max(r_max,height[j]);
}
for(int j = i;j >= 0;j--){
l_max = Math.max(l_max,height[j]);
}
int x = Math.min(r_max,l_max) - height[i];
res = res + x;
}
return res;
}
public static int trap2(int[] height) {
int n = height.length;
int res = 0;
int[] l_max = new int[n];
int[] r_max = new int[n];
l_max[0] = height[0];
r_max[n-1] = height[n-1];
//l_max[i]表示位置 i 左边最高的柱子高度,r_max[i]表示位置 i 右边最高的柱子高度。
for(int j = 1;j < n;j++){
l_max[j] = Math.max(l_max[j-1],height[j]);
}
for(int j = n-2;j >= 0;j--){
r_max[j] = Math.max(r_max[j+1],height[j]);
}
for(int i = 1;i < n-1;i++){
res += Math.min(r_max[i],l_max[i]) - height[i];
}
return res;
}
//双指针法
public static int trap3(int[] height) {
int n = height.length;
int res = 0;
int left = 0;
int right = n - 1;
int l_max = height[0];
int r_max = height[n-1];
while(left <=right){
l_max = Math.max(l_max,height[left]);
r_max = Math.max(r_max,height[right]);
if(l_max < r_max){
res += l_max - height[left];
left++;
}else{
res += r_max - height[right];
right--;
}
}
return res;
}
}
class Solution {
public int trap(int[] height) {
int n = height.length;
if (n == 0) {
return 0;
}
int[] leftMax = new int[n];
leftMax[0] = height[0];
for (int i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
int[] rightMax = new int[n];
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
}
//双指针
class Solution {
public int trap(int[] height) {
int sum = 0;
//排除首尾
for(int i = 1;i < height.length - 1;i++){
int left = height[i];
int right = height[i];
//找左边最高的
for(int l = i - 1;l >= 0;l--){
if(height[l] > left){
left = height[l];
}
}
for(int r = i + 1;r < height.length;r++){
if(height[r] > right) {
right = height[r];
}
}
//记录当前能积攒的雨水
int h = Math.min(left,right) - height[i];
if(h > 0) sum += h;
}
return sum;
}
}
共以下 10 个回答
两种方法,双指针节省空间复杂度
双指针,巧妙避开DP
时间O(n)
空间O(n)
双指针法时间复杂度为O(n),空间复杂度为O(1)
时间:O(n),空间:O(n)
//使用动态规划,不过这题目最好的还是单调栈& height) { l(height.size(),0); r(height.size(),0);
class Solution {
public:
int trap(vector
int res=0;
vector
vector
l[0]=height[0];
r[height.size()-1]=height[height.size()-1];
for(int i=1;i<height.size();++i){
l[i]=max(height[i],l[i-1]);
}
for(int i=height.size()-2;i>=0;–i){
r[i]=max(height[i],r[i+1]);
}
for(int i=1;i<height.size()-1;++i){
};
双指针。时间复杂度O(n^2)空间复杂度O(n)