力扣-2865美丽塔Ⅰ

美丽塔Ⅰ

给定一个长度为n下标为0开始的整数数组maxHeights

需要在坐标轴上建n坐塔。第i座塔的下标为i,高度为heights[i]

如果以下条件满足,我们称这些塔是 美丽 的:

  1. 1 <= heights[i] <= maxHeights[i]
  2. 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
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎丶辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值