题目: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))
拖了三天的接雨水来了