leetcode 42. 接雨水

2023.8.29

         本题可以用双指针做,求出每一列能盛的雨水,再相加即可。不过暴力法会超时,需要优化。

双指针(暴力):

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        for(int i=1; i<height.size()-1; i++)
        {
            int max_rheight = height[i]; //记录当前柱子右边的最高柱子
            int max_lheight = height[i]; //记录当前柱子左边的最高柱子
            for(int r=i+1; r<height.size(); r++)
            {
                max_rheight = max(max_rheight,height[r]);
            }
            for(int l=i-1; l>=0; l--)
            {
                max_lheight = max(max_lheight,height[l]);
            }
            ans += max(0 , min(max_rheight,max_lheight)-height[i]);
        }
        return ans;
    }
};

双指针(优化):

        上面双指针暴力法每次遍历都需要求一次当前柱子左右两侧的最高柱子,这样有重复,自然会超时。 优化办法是设置两个数组left和right,分别存储每一个柱子的左侧最高柱子,及右侧最高柱子,这样子就不用重复遍历了。 代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        //求出当前柱子的左侧最高柱子以及右侧最高柱子,保存在两数组中。
        vector<int> left(height.size());
        vector<int> right(height.size());
        int max_lheight = height[0];
        int max_rheight = height[height.size()-1];
        for(int i=1; i<left.size()-1; i++)
        {
            left[i] = max_lheight;
            max_lheight = max(max_lheight,height[i]);
        }
        for(int i=right.size()-2; i>=1; i--)
        {
            right[i] = max_rheight;
            max_rheight = max(max_rheight,height[i]);
        }
        //遍历每一列求出最大雨水
        int ans = 0;
        for(int i=1; i<height.size()-1; i++)
        {
            ans += max(0 , min(left[i],right[i])-height[i]);
        }
        return ans;
    }
};

2023.10.1

        二刷。 还是原来的思路,用left和right数组记录当前柱子左侧的最大柱子 和 当前柱子右侧的最大柱子,但是第一个柱子和最后一个柱子不需要记录,因为这两个柱子不能储水。

        最近开始学java,用java撸的代码:

class Solution {
    public int trap(int[] height) {
        int left[] = new int [height.length];
        int right[] = new int [height.length];
        int left_max = height[0];
        int right_max = height[height.length-1];
        //不需要遍历到数组的首元素和尾元素
        for(int i=1; i<height.length-1; i++){
            left[i] = left_max;
            left_max = Math.max(left_max,height[i]);
        }
        for(int i=height.length-2; i>=1; i--){
            right[i] = right_max;
            right_max = Math.max(right_max,height[i]);
        }
        //求面积和
        int ans = 0;
        for(int i=1; i<height.length-1; i++){
            ans += Math.max(0 , Math.min(left[i],right[i])-height[i]);
        }
        return ans;
    }
}

        还是有点不习惯的,比如max要用Math.max,.size()变成了.length。数组的定义也有点区别,慢慢熟悉把。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值