当前位置:首页 > 力扣 > 力扣2012题:使用动态规划解决数组美丽值求和

力扣2012题:使用动态规划解决数组美丽值求和

2个月前 (08-06)

力扣2012题:使用动态规划解决数组美丽值求和 力扣题解 动态规划 C++ 第1张

一、题目解读

力扣2012题要求计算数组中所有“美丽数”的总和。美丽数定义为:数组中满足“中间元素同时大于左右相邻元素”或“中间元素同时小于左右相邻元素”的数值。例如,[3,1,2,4]中,1和2均为美丽数,总和为3。

二、解题思路

采用动态规划预处理极值的解法,核心思想:

1. 预处理左右极值:

○ 计算每个位置左侧的最大值(left_max),从前往后遍历,更新当前位置的最大值;

○ 计算每个位置右侧的最小值(right_min),从后往前遍历,更新当前位置的最小值。

2. 遍历中间元素:

○ 若中间元素同时大于left_max和小于right_min,则为严格美丽数,贡献2分;

○ 若中间元素仅满足“山谷”或“山峰”(即两侧相邻元素递增或递减),贡献1分。

3. 累加所有贡献得到总和。

关键在于通过预处理减少重复比较,将O(n^2)复杂度降为O(n)。

三、解题步骤

1. 预处理左侧最大值left_max:

○ 初始化left_max[0] = nums[0],即第一个元素为左侧最大值;

○ 遍历i=1至n-1,更新left_max[i] = max(left_max[i-1], nums[i])。

2. 预处理右侧最小值right_min:

○ 初始化right_min[n-1] = nums[n-1],即最后一个元素为右侧最小值;

○ 逆序遍历i=n-2至0,更新right_min[i] = min(right_min[i+1], nums[i])。

3. 计算美丽值总和:

○ 遍历i=1至n-2(中间元素),分情况累加:

■ 若nums[i] > left_max[i-1]且nums[i] < right_min[i+1],贡献2分;

■ 若nums[i-1] < nums[i]且nums[i] > nums[i+1](山谷),或反之(山峰),贡献1分。

4. 返回总分数res。

四、代码与注释

class Solution {
public:
    int sumOfBeauties(vector<int>& nums) {
        int n = nums.size();
        vector<int> left_max(n), right_min(n);
        
        // 预处理左边最大值
        left_max[0] = nums[0];
        for (int i = 1; i < n; ++i) {
            left_max[i] = max(left_max[i-1], nums[i]);
        }
        
        // 预处理右边最小值
        right_min[n-1] = nums[n-1];
        for (int i = n-2; i >= 0; --i) {
            right_min[i] = min(right_min[i+1], nums[i]);
        }
        
        int res = 0;
        // 计算每个中间元素的美丽值
        for (int i = 1; i < n-1; ++i) {
            if (left_max[i-1] < nums[i] && nums[i] < right_min[i+1]) {
                res += 2;
            } else if (nums[i-1] < nums[i] && nums[i] < nums[i+1]) {
                res += 1;
            }
        }
        return res;
    }
};

注释说明:

● left_max[i] = max(...):动态规划核心,确保每个位置记录左侧最大极值;

● if (left_max[i-1] < nums[i]...:通过预处理结果直接判断美丽数类型,无需重复比较。

五、总结

本文通过动态规划预处理左右极值,高效求解美丽数总和。核心优势在于:

1. 空间换时间:通过O(n)预处理避免O(n^2)比较;

2. 清晰的分情况讨论:严格美丽数与“山谷/山峰”贡献不同分值;

3. 简洁代码实现,无需额外数据结构

算法时间复杂度O(n),空间复杂度O(n),为数组优化问题的典型解法,适用于需要高效处理局部极值的场景,适合算法竞赛与编程学习参考。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣35:二分法在搜索插入位置中的运用

力扣35:二分法在搜索插入位置中的运用

有序数组的定位在一个严格递增的数字序列中,每个元素都有其确定的位置。当新元素试图加入时,我们需要回答两个问题:它是否已经存在?如果不存在,它应该插入在哪里?这道题要求我们在O(log n)时间内完成这...

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

一、题目解读2019年CSP-J的“纪念品”问题(对应洛谷P5662)要求玩家在T天内通过买卖纪念品最大化金币收益。每天可交易N种商品,需计算最优策略下的最终金币数。题目强调动态规划思维与资源分配优化...

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

一、题目解读题目要求在一个n×m的网格中,从左上角到右下角选择一条路径,路径上的数字可重复取用,求取数之和的最大值。路径限制为仅能向右或向下移动。需注意路径的灵活性与重复取数的可能性,传统单向动态规划...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。