135. 分发糖果

题目:n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:(1)每个孩子至少分配到 1 个糖果 。(2)相邻两个孩子评分更高的孩子会获得更多的糖果。请你给每个孩子分发糖果,计算并返回需要准备的最少糖果数目 。

本题需注意第二个条件,一个孩子获取的糖果数需要和左右两边的孩子相比较,而不能只和一边的孩子相比较。因此左右两边都需要贪心算法:

(1)从左到右

局部最优:只要右边评分比左边大,右边的孩子就多一个糖果

全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果

cpp 复制代码
// 从前向后
for (int i = 1; i < ratings.size(); i++) {
    if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
}

(2)从右到左

局部最优:取candyVeci + 1 + 1 和 candyVeci 最大的糖果数量(candyVeci只有取最大的才能既保持对左边candyVeci - 1的糖果多,也比右边candyVeci + 1的糖果多。 ),保证第i个小孩的糖果数量既大于左边的也大于右边的

全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。(从右到左一定要从后向前遍历,因为左孩子大于右孩子的情况需要用上右孩子的比较情况)

cpp 复制代码
// 从后向前
for (int i = ratings.size() - 2; i >= 0; i--) {
    if (ratings[i] > ratings[i + 1] ) {
        candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
    }
}

整体代码如下:

cpp 复制代码
class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(), 1);
        // 从前向后
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
        }
        // 从后向前
        for (int i = ratings.size() - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1] ) {
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
            }
        }
        // 统计结果
        int result = 0;
        for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
        return result;
    }
};
相关推荐
.道阻且长.8 小时前
2.LeetCode算法习题讲解--双指针--复写零
算法·leetcode·职场和发展
To_OC10 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
白狐_79810 小时前
408数据结构第5章:二叉树遍历序列题——技巧、判断与真题型总结
数据结构
Forever Nore13 小时前
学完C语言力扣第一题做不来正常吗
数据结构·算法
hansang_IR13 小时前
【题解】LC:倍增 / 区间并查集(Range Parallel Unionfind)
c++·算法·并查集
Tisfy15 小时前
LeetCode 3731.找出缺失的元素:哈希 / 排序
算法·leetcode·哈希算法·排序·哈希表
lucas_AI15 小时前
Q-CueGraph:你的多模态大模型会 zoom,但真的知道该看哪儿吗?
人工智能·算法
kaixin_啊啊16 小时前
test_机器学习算法学习
学习·算法·机器学习
liulilittle16 小时前
MOE路由:路由(logits: top-k/8)
c++·人工智能·算法·机器学习·llm