对撞双指针+前缀和分解

题目:LeetCode(42.接雨水)

https://leetcode.cn/problems/trapping-rain-water/description/

题目描述:

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

示例:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

审题:

        1.给定 n 个非负整数表示每个宽度为 1 的柱子的高度图

        2.计算按此排列的柱子,下雨之后能接多少雨水。

思路:

怎么也才能接到水呢?我们将蓝色区域的洼地看作为一个桶。只要桶左右两侧比桶高时就能接到水。并且接到水的量取决于左边有两侧矮的那一侧

 这里的前缀和后缀分解实际上就是一直找最高的板子(前面找到的与实际高度的比较)。最后以高的板子为基准

代码(前后缀分解:牺牲空间版):

# 时间复杂度O(3n)
# 空间复杂度O(n)
ans_max_warter = 0
n = len(height)
#定义前缀数组
pre_max = [0]*n
pre_max[0] = height[0]
#定义后缀数组
suf_max = [0]*n
suf_max[-1] = height[-1]

for i in range(1,n):
    pre_max[i] = max(pre_max[i-1],height[i]) # 找高的那个板子
for j in range(n-2,-1,-1):
    suf_max[j] = max(suf_max[j+1],height[j])
for h,pre,suf in zip(height,pre_max,suf_max):
    ans_max_warter += min(pre,suf)-h
print(ans_max_warter)
        

代码(前后缀分解对撞指针版):

def trap(height):
    #时间复杂度O(n)
    # 空间复杂度O(1)
    n = len(height)
    ans_max_warter = 0
    left = 0
    right = n - 1
    pre_max = 0
    suf_max = 0
    while left <= right:
        pre_max = max(pre_max, height[left])
        suf_max = max(suf_max, height[right])
        if pre_max < suf_max:
            ans_max_warter += pre_max - height[left]
            left += 1
        else:
            ans_max_warter += suf_max - height[right]
            right -= 1
    return ans_max_warter

题目:

https://www.dotcpp.com/oj/problem2664.html

 

def All_sum(n,li):
    impact = sum(li)
    smr = 0
    for i in range(n):
        impact -= li[i]
        smr += li[i] * impact
    return smr


if __name__ == '__main__':
    n=int(input())
    li=list(map(int, input().split()))
    print(All_sum(n,li))

拖了三天的接雨水来了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值