2012. 数组美丽值求和

【算法题解析】数组中的美丽值统计(美丽值之和)

✨题目描述

给定一个下标从 0 开始的整数数组 nums。对每个下标 i(满足 1 <= i <= nums.length - 2),我们定义一个整数的 美丽值(beauty),具体规则如下:

  • 美丽值为 2:如果存在 j < i < k,满足 nums[j] < nums[i] < nums[k]
  • 美丽值为 1:如果不满足上面的条件,但满足 nums[i-1] < nums[i] < nums[i+1]
  • 美丽值为 0:如果以上条件都不满足。

请你返回所有 1 <= i <= nums.length - 2 范围内的 nums[i]美丽值总和


✅ 示例 1:

输入:nums = [1, 2, 3]
输出:2
解释:
对于 i = 1:
  nums[0] < nums[1] < nums[2] => 1 < 2 < 3,满足美丽值为 2。
总和为 2。

✅ 示例 2:

输入:nums = [2, 4, 6, 4]
输出:1
解释:
对于 i = 1:nums[0] = 2 < 4 < 6 = nums[2],美丽值 = 2;
对于 i = 2:nums[1] = 4 < 6 > 4 = nums[3],不满足美丽值2,也不满足美丽值1;
因此总和为 2 + 0 = 2。
但实际上 leftMax[1] = 4,nums[2] = 6,不满足 leftMax < nums[2],所以美丽值为 1(满足 nums[1] < nums[2] > nums[3]),总和为 1。

✅ 示例 3:

输入:nums = [3, 2, 1]
输出:0
解释:
对于 i = 1:nums[0] = 3 > 2 > 1 = nums[2],不满足任何条件。

🧠 解题思路分析

核心目标

我们需要针对每一个中间元素 nums[i] (1 <= i <= n-2),判断它是否满足:

  1. 有一个左边的元素小于它,且右边有一个元素大于它(美丽值 = 2)
  2. 或者左右相邻元素满足 nums[i-1] < nums[i] < nums[i+1](美丽值 = 1)
  3. 否则(美丽值 = 0)

为了高效完成这个判断,我们可以预处理:

  • 每个位置左边的最大值 leftMax[i]
  • 每个位置右边的最小值 rightMin[i]

为什么这样处理?

我们并不需要枚举所有的 j < ik > i,只需要知道:

  • nums[i] 是否大于它左边的所有值(即大于 leftMax[i-1]
  • nums[i] 是否小于它右边的所有值(即小于 rightMin[i+1]

如果这两个条件都满足,那么一定存在某个 jk 使得 nums[j] < nums[i] < nums[k] 成立,从而美丽值为 2。


🛠 解题方法(Python 实现)

from typing import List

class Solution:
    def sumOfBeauties(self, nums: List[int]) -> int:
        n = len(nums)
        leftMax = [0] * n
        rightMin = [0] * n

        # 构造左侧最大值数组
        leftMax[0] = nums[0]
        for i in range(1, n):
            leftMax[i] = max(leftMax[i - 1], nums[i])

        # 构造右侧最小值数组
        rightMin[-1] = nums[-1]
        for i in range(n - 2, -1, -1):
            rightMin[i] = min(rightMin[i + 1], nums[i])

        total_beauty = 0
        for i in range(1, n - 1):
            if leftMax[i - 1] < nums[i] < rightMin[i + 1]:
                total_beauty += 2
            elif nums[i - 1] < nums[i] < nums[i + 1]:
                total_beauty += 1
            # 否则为0,省略不加

        return total_beauty

⏱ 时间复杂度与空间复杂度

操作复杂度
时间复杂度O(n)
三次线性扫描:一次构造 leftMax
,一次构造 rightMin
,一次遍历判断
空间复杂度O(n)
需要两个额外数组存储最大/最小值

该解法已经是线性时间和线性空间的最优解,适用于数组长度在 10^5 级别的情况。


🔍 方法分析与对比

方法优点缺点
枚举 j 和 k(暴力法)容易理解时间复杂度 O(n²),不可接受
前后缀数组法(本解法)时间复杂度 O(n),适配大数据需要额外 O(n) 空间

✅ 总结

这道题考察了对区间最值的预处理技巧:

  • 类似于“前缀最大值”“后缀最小值”这种技巧在很多问题中都非常常用,比如“下一个更大元素”、“最大子数组”等。
  • 本题的本质是利用这些前缀/后缀信息,避免了不必要的暴力枚举,达到了线性优化效果。
用户界面: 1. 数组输入:请输入数组的长度:(用户输入长度) 请输入数组的元素:(用户输入元素,以空格分隔) 数组输入成功! 2. 数组排序:请选择排序方式: 1. 升序排序 2. 降序排序 (用户选择排序方式) 排序成功! 3. 元素插入:请输入要插入的元素:(用户输入元素) 请输入要插入的位置:(用户输入位置) 插入成功! 4. 元素查找:请输入要查找的元素:(用户输入元素) 元素查找成功!该元素在数组中的位置为:(输出位置) 5. 元素删除:请输入要删除的元素:(用户输入元素) 元素删除成功! 6. 数组输出:数组元素为:(输出数组元素) 7. 输出指定位置元素:请输入要查询的位置:(用户输入位置) 该位置的元素为:(输出元素) 8. 对指定个数的数组元素求和:请输入要求和的个数:(用户输入个数) 数组元素求和为:(输出求和结果) 9. 实验报告: 本次实验设计了一个整型数组操作库,实现了数组输入、数组排序、元素插入、元素查找、元素删除、数组输出、输出指定位置元素、对指定个数的数组元素求和等功能。 在用户界面中,用户可以输入数组的长度和元素,进行数组的初始化;也可以选择升序或降序排序方式,进行数组排序;可以插入元素,查找元素,删除元素;输出数组元素和指定位置的元素;求和指定个数的数组元素。 实验中,我们使用了冒泡排序算法进行数组排序,使用了数组下标进行元素插入和删除操作。同时,我们对用户的输入进行了合法性判断,保证了程序的稳定性和正确性。 本次实验让我对数组操作有了更深入的理解,也锻炼了我的编程能力和问题解决能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值