力扣第42题 接雨水

原文链接
原文是带着图片讲解,过程还算详细
在这里插入图片描述
上题是一个对题目的举例说明
本次解题中用这个图
在这里插入图片描述
我认为这个图涵盖了可能出现的情况,讲解会比较好一点
第一种方法是暴力法,时间复杂度为O (n^2) 空间复杂度为O(1)

public int trap02(int[] height) { 
    int sum = 0;   
    //最两端的列不用考虑,因为一定不会有水。所以下标从 1 到 length - 2    
    for (int i = 1; i < height.length - 1; i++) { 
        int max_left = 0;       
        //找出左边最高        
        for (int j = i - 1; j >= 0; j--) {  
            if (height[j] > max_left) {  
                max_left = height[j];  
            }       
        }        
        int max_right = 0;       
        //找出右边最高       
        for (int j = i + 1; j < height.length; j++) { 
            if (height[j] > max_right) {  
                max_right = height[j];   
            }       
        }       
        //找出两端较小的       
        int min = Math.min(max_left, max_right); 
        //只有较小的一段大于当前列的高度才会有水,其他情况不会有水  
        if (min > height[i]) { 
            sum = sum + (min - height[i]);       
        }   
    }   
    return sum;
}

每一步的前进都让 当前元素的前边和后边比较,找出前边后边的最小值然后再和当前元素比较,看是否能放入水,代码不好直接阅读的话可用箭头在上图中来一步一步前进
,画图有助于理解

第二种方法为双指针法
具体分析可以点文章开头的原文阅读,此处稍微提及

在这里插入图片描述
大体的思想就是从左右两边开始遍历 如果左边的最高的小于右边的最高的,那么就从左边开始前进,找能存放的水量,反之也一样,在指针前进的过程中更新最大值,通过两边的最大值比较到底应该从哪边走,因为存水量取决于最小的那一端

public int trap(int[] height) {
    if (height.length == 0) return 0;
    int left = 0;
    int right = height.length-1;
    int leftMax = 0;
    int rightMax = 0;
    int result = 0;
    while (left <= right) {
      if (leftMax < rightMax) {
        result += leftMax - height[left] > 0 ?
            leftMax - height[left] : 0;
        leftMax = Math.max(leftMax, height[left]);
        left++;
      } else {
        result += rightMax - height[right] > 0 ?
            rightMax - height[right] : 0;
        rightMax = Math.max(rightMax, height[right]);
        right--;
      }
    }
    return result;
  }

时间复杂度为O(n^2)空间复杂度为O(1)
第三种方法是按照行求
具体看原文
https://leetcode-cn.com/problems/trapping-rain-water/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-8/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌晨里的无聊人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值