美丽塔Ⅰ
给定一个长度为n
下标为0
开始的整数数组maxHeights
。
需要在坐标轴上建n
坐塔。第i
座塔的下标为i
,高度为heights[i]
如果以下条件满足,我们称这些塔是 美丽 的:
1 <= heights[i] <= maxHeights[i]
heights
是一个 山脉 数组。
如果存在下标 i
满足以下条件,那么我们称数组 heights
是一个 山脉 数组:
- 对于所有
0 < j <= i
,都有heights[j - 1] <= heights[j]
- 对于所有
i <= k < n - 1
,都有heights[k + 1] <= heights[k]
请你返回满足 美丽塔 要求的方案中,高度和的最大值 。
示例 1:
输入:maxHeights = [5,3,4,1,1]
输出:13
解释:和最大的美丽塔方案为 heights = [5,3,3,1,1] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山脉数组,峰值在 i = 0 处。
13 是所有美丽塔方案中的最大高度和。
示例 2:
输入:maxHeights = [6,5,3,9,2,7]
输出:22
解释: 和最大的美丽塔方案为 heights = [3,3,3,9,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山脉数组,峰值在 i = 3 处。
22 是所有美丽塔方案中的最大高度和。
示例 3:
输入:maxHeights = [3,2,5,5,2,3]
输出:18
解释:和最大的美丽塔方案为 heights = [2,2,5,5,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山脉数组,最大值在 i = 2 处。
注意,在这个方案中,i = 3 也是一个峰值。
18 是所有美丽塔方案中的最大高度和。
提示:
1 <= n == maxHeights <= 103
1 <= maxHeights[i] <= 109
分析:
仔细读题,然后分析山脉数组的条件,我们发现,
- 数组
maxHeights
中第i个元素就是这个最高的塔 - 在这个最高塔的左边塔高依次减少。在这个最高塔的右边塔高依次减少。
这样就好说了,我们假设第i个塔是最高的,然后根据条件得出左右每个位置上可以建造的最高的塔即可。
根据此我们可以得到所有的情况。代码如下:
def f(maxHeights: list):
'''
思路整理:根据条件可以整理出:第i坐塔为最高的。
在第i坐塔的左边依次递减,右边依次递减。
最后返回 最高峰在i处 最大高度 (我只要 - 美丽塔的方案)
假设第i个为最高峰,计算出结果。存放在一个列表中然后进行比较。
:param maxHeights:山峰数组
:return:null
'''
# n是列表长度
n = len(maxHeights)
all_res = []
# 以i为最高峰以此进行计算,得到所有的方案
for i in range(n):
copy = list(maxHeights) # 复制一份出来
maxHeight = maxHeights[i] # 当前可以使用的最大值
for j in range(i - 1, -1, -1):
if maxHeights[j] >= maxHeight:
copy[j] = maxHeight
else:
maxHeight = maxHeights[j]
copy[j] = maxHeight
maxHeight = maxHeights[i] # 计算右边的时候将可使用的最大值恢复
for j in range(i + 1, n):
if maxHeights[j] >= maxHeight:
copy[j] = maxHeight
else:
maxHeight = maxHeights[j]
copy[j] = maxHeight
#如果直接存入会在第二次执行时改变上一次的值。因为存进去的其实是地址。
# all_res.append(copy)
all_res.append(list(copy))
return all_res
我们使用测试用例[5, 3, 4, 1, 1]
尝试输出all_res
如下图:
然而我们题目要求是:请你返回满足 美丽塔 要求的方案中,高度和的最大值 。
此时我们就有了两种方案,在后续直接处理我们得到的all_res
,另一种是修改过程代码(因为逻辑是一样的),在过程中将高度和计算出来,保留最大值。
从为了完成题目的思路来讲,我们使用第一种方式,但是从优化角度来讲,我们应该使用第二种思路。
第一种思路:–将上面代码的return all_res
替换为以下代码即可。
# 存储高度和的最大值
maxHeights_total = 0
for towers in all_res:
# 单次情况计算高度和的最大值
total = 0
for tower in towers:
total += tower
# 只保留最大值
if total > maxHeights_total:
maxHeights_total = total
return maxHeights_total
第二种思路: --需要修改代码细节。
def f(maxHeights: list):
'''
思路整理:根据条件可以整理出:第i坐塔为最高的。
在第i坐塔的左边依次递减,右边依次递减。
最后返回 最高峰在i处 最大高度 (我只要 - 美丽塔的方案)
假设第i个为最高峰,计算出结果。存放在一个列表中然后进行比较。
:param maxHeights:山峰数组
:return:null
'''
# n是列表长度
n = len(maxHeights)
maxHeights_total = 0
# all_res = []
# 以i为最高峰以此进行计算,得到所有的方案
for i in range(n):
# copy = list(maxHeights) # 复制一份出来
maxHeight = maxHeights[i] # 当前可以使用的最大值
total = maxHeight
# 计算左边
for j in range(i - 1, -1, -1):
if maxHeights[j] >= maxHeight:
total += maxHeight
else:
maxHeight = maxHeights[j]
total += maxHeight
maxHeight = maxHeights[i] # 计算右边的时候将可使用的最大值恢复
# 计算右边
for j in range(i + 1, n):
if maxHeights[j] >= maxHeight:
total += maxHeight
else:
maxHeight = maxHeights[j]
total += maxHeight
if total > maxHeights_total:
maxHeights_total = total
return maxHeights_total