class Solution {
public int trap(int[] height) {
if(height.length 0)
return 0;
int n = height.length;
int left = 0, right = n-1;
int ans = 0;
int l_max = height[0];
int r_max = height[right];
class Solution {
public:
int trap(vector<int>& height) {
// 简化问题就只考虑height[i]能接的雨水
// ans = max(height[i],min(lmax,rmax)) - height[i];
int n = height.size();
int lmax = height[0];
int rmax = height[n-1];
int left = 0;
int right = n - 1;
int ans = 0;
while(left <= right){
lmax = max(height[left],lmax);
rmax = max(height[right],rmax);
if(lmax < rmax){
ans += lmax - height[left];
left++;
}
else{
ans += rmax - height[right];
right--;
}
}
return ans;
}
};
function trap(height: number[]): number {
let prev = new Array(height.length);
let last = new Array(height.length);
let res = 0;
prev[0] = height[0];
for (let i = 1; i < height.length; i++) {
prev[i] = Math.max(prev[i - 1], height[i]);
}
last[height.length - 1] = height.slice(-1)[0];
for (let i = height.length - 2; i >= 0; i--) {
last[i] = Math.max(height[i],last[i+1]);
}
for(let i = 0; i < height.length; i ++ ) {
res += Math.min(prev[i],last[i]) - height[i];
}
return res;
};
class Solution {
//双向指针
//以最短的柱子来计算,从两边往中间遍历
public int trap(int[] height) {
int res = 0;
int l = 0, r = height.length - 1;
int pre_max = height[l];
int suf_max = height[r];
while(l < r){
pre_max = Math.max(pre_max, height[l]);
suf_max = Math.max(suf_max, height[r]);
if(pre_max < suf_max){
res += pre_max - height[l];
l ++;
}else{
res += suf_max - height[r];
r--;
}
}
return res;
}
}
class Solution {
public int trap(int[] height) {
int res = 0;
int l = 0, r = height.length - 1;
int pre_max = height[l];
int suf_max = height[r];
while(l < r) {
pre_max = Math.max(pre_max,height[l]);
suf_max = Math.max(suf_max,height[r]);
if(pre_max < suf_max) {
res += pre_max - height[l];
l ++;
} else {
res += suf_max - height[r];
r --;
}
}
return res;
}
}
class Solution {
public int trap(int[] height) {
//动态规划,对方法二的优化。使时间复杂度从On2降低到On
int sum = 0;
int n = height.length;
int[] max_left = new int[n];
int[] max_right = new int[n];
for(int i = 1; i < n - 1; i++){
max_left[i] = Math.max(max_left[i - 1], height[i - 1]);
}
for(int i = n - 2; i >= 0; i--){
max_right[i] = Math.max(max_right[i + 1], height[i + 1]);
}
for(int i = 1; i < n - 1 ; i++){
int min = Math.min(max_left[i], max_right[i]);
if (min > height[i]) {
sum = sum + (min - height[i]);
}
}
return sum;
}
}
共以下 10 个回答
class Solution {
public int trap(int[] height) {
if(height.length 0)
return 0;
int n = height.length;
int left = 0, right = n-1;
int ans = 0;
int l_max = height[0];
int r_max = height[right];
}
做了好几次这次还是忘了,明明会
时间复杂度:O(n)
空间复杂度:O(n)
常规题
相向双指针
木桶效应,以短的木板来计算实际水量,两边一起往中间遍历
8.8 周二
Day29:下面是代码
class Solution {
public int trap(int[] height) {
///通过列计算 找到每列左右的最高墙 左右最高找里面最小的那个座位短板
//1.如果当前列<短板 可以存水
//2. >=短板无法存水
int maxleft[]=new int[height.length];
int maxright[]=new int[height.length];
maxleft[0]=height[0];
int sum= 0;
for(int i=1;i<height.length;i++)
{
maxleft[i]=Math.max(maxleft[i-1],height[i]);
}
maxright[height.length-1]=height[height.length-1];
for(int i=height.length-2;i>=0;i–)
{
maxright[i]=Math.max(maxright[i+1],height[i]);
}
for(int i=1;i<height.length-1;i++)
{
if(height[i]<Math.min(maxleft[i],maxright[i]))
{
sum=sum+Math.min(maxleft[i],maxright[i]) – height[i];
}
}
return sum;
}
}