LeetCode - 解题笔记 - 42 -Trapping Rain Water

Trapping Rain Water

Solution 1

这个题乍一看应该是之前存水问题的变体,所以还是一个使用双指针维护的问题。我一开始还是希望和存水问题一样的思路,但是计算水量的过程变成了一个子遍历。后面发现每一个格的水量计算是线性时间的:找到两侧高于当前占位的最高值中较小的一个,计算差值即可,即min(maxLeft, maxRight) - height[current]。因此需要对双指针的遍历逻辑进行改动,增加两个分别维护左侧最大和右侧最大的状态量,左右指针分别有可能更新各自一侧的最大值。因此遍历逻辑如下:

  1. 如果当前左侧指针更小,那么必然左侧计算更加稳妥(因为计算结果依赖于较短的一侧),考察左侧是替换最大值还是计算存水量
  2. 对应地,如果右侧指针更小,右侧计算更加稳妥,考察右侧
  • 时间复杂度: O ( n ) O(n) O(n) n n n为输入长度,双指针遍历
  • 空间复杂度: O ( 1 ) O(1) O(1),仅维护常数个状态变量
class Solution {
public:
    int trap(vector<int>& height) {
        int left = 0, right = height.size() - 1;
        int ans = 0;
        int maxLeft = 0, maxRight = 0;
        
        while (left < right) {
            // cout << left << ": " <<  height[left] << " " << maxLeft << " -- " << right << ": " << height[right] << " " << maxRight << " -- " << ans << endl;
            if (height[left] < height[right]) {
                // 此时,所有的位置的计算以左侧为准,但是只有左侧的才能计算准确
                if (height[left] > maxLeft) {
                    maxLeft = height[left];
                }
                else {
                    ans += maxLeft - height[left];
                }
                left ++;
            }
            else {
                // 同理,此时所有的计算以右侧为准,但只有右侧的才能计算准确
                if (height[right] > maxRight) {
                    maxRight = height[right];
                }
                else {
                    ans += maxRight - height[right];
                }
                right --;
            }
        }
        return ans;
    }
};

Solution 2

Solution 1的Python实现

class Solution:
    def trap(self, height: List[int]) -> int:
        left = 0
        right = len(height) - 1
        
        ans = 0
        maxLeft = 0
        maxRight = 0
        
        while left < right:
            if height[left] < height[right]:
                if height[left] > maxLeft: maxLeft = height[left]
                else: ans += maxLeft - height[left]
                    
                left += 1
            else:
                if height[right] > maxRight: maxRight = height[right]
                else: ans += maxRight - height[right]
                    
                right -= 1
                
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值