【LeetCode|Hot100】No:7接雨水

注:

本系列文章仅是作者自己学习过程中记录的笔记,是初学python用于算法求解的过程,会含有很多对于python的个人注解,用于学习。求职中解算法,我打算使用Python来进行解答,不知是否可不可以,希望能得到大佬的建议,轻喷。

题目:

定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

(自创)双指针法:

时间复杂度:超出LC限制

原理:主要是利用双指针思想,左边找一个柱子 → 向右找一个比它高/相等的柱子 → 中间的部分能装水,如果右边找不到比左边高的柱子,就找右边最高的柱子,形成坑洞来进行计算。但此法耗时过长。

class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        water = 0
        left = 0
        while left < n - 1:
            if height[left] == 0:
                left += 1
                continue
            right = left + 1
            mid = 0
            # 找右边第一个 >= height[left] 的柱子
            while right < n and height[right] < height[left]:
                mid += height[right]
                right += 1
            if right < n:
                # 找到了右边界
                water += (right - left - 1) * min(height[left], height[right]) - mid
                left = right
            else:
                # 右边没找到比 left 高的柱子 -> 找右边最高的柱子
                max_pos = left + 1
                for i in range(left + 1, n):
                    if height[i] >= height[max_pos]:
                        max_pos = i
                mid = sum(height[left+1:max_pos])
                water += (max_pos - left - 1) * min(height[left], height[max_pos]) - mid
                left = max_pos
        return water
        

#mid = sum(height[left+1:max_pos]):----------计算从left+1到max_pos的height的总和

双指针法:

时间复杂度:O(N)

原理:双指针法是“一格一格算”,用左右最高值来判断,保证每格的水量只需要一次计算就能确定。一格一格地判断右边的格子能不能存水。

class Solution:
    def trap(self, height: List[int]) -> int:
        ans = 0
        left, right = 0, len(height) - 1
        leftMax = rightMax = 0
​
        while left < right:
        # 更新左右最高柱子
            leftMax = max(leftMax, height[left])
            rightMax = max(rightMax, height[right])
​
            if height[left] < height[right]:
             # 左边矮 → 左边的水量已经可以确定
                ans += leftMax - height[left]
                left += 1
            else:
            # 右边矮 → 右边的水量已经可以确定
                ans += rightMax - height[right]
                right -= 1
                
        return ans

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值