代码训练LeetCode(26)分发糖果

代码训练(25)LeetCode之加油站

Author: Once Day Date: 2025年6月9日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-优快云博客

参考文章:

1. 原题

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

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目

提示:

  • n == ratings.length
  • 1 <= n <= 2 * 104
  • 0 <= ratings[i] <= 2 * 104

示例:

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
     第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
2. 分析

这道题目要求是给一排孩子分配糖果,每个孩子至少要有一个糖果。如果一个孩子的评分比他相邻的孩子高,那么这个孩子需要得到比相邻孩子更多的糖果。我们的目标是计算出满足这些条件的情况下,需要的最少糖果数量。

解题思路

为了满足题目中的要求,我们可以采用两次遍历的策略:

  1. 从左到右遍历:保证每个孩子与他左边的孩子相比,如果评分高,则糖果数也要比左边多。
  2. 从右到左遍历:保证每个孩子与他右边的孩子相比,如果评分高,则糖果数也要比右边多。

具体步骤如下:

  • 初始化一个数组 candy,长度等于 ratings 的长度,每个元素初始值为 1(因为每个孩子至少一个糖果)。
  • 第一次遍历:从左向右遍历 ratings 数组,如果 ratings[i] 大于 ratings[i-1],则 candy[i] 更新为 candy[i-1] + 1
  • 第二次遍历:从右向左遍历 ratings 数组,如果 ratings[i] 大于 ratings[i+1],则 candy[i] 更新为 max(candy[i], candy[i+1] + 1)

性能优化关键点

  • 空间优化:在这个解决方案中,除了输入数组外,我们额外使用了一个整数数组来存储糖果数。这是必要的,因为我们需要存储每个孩子的糖果数以进行比较。
  • 时间优化:整个解决方案的时间复杂度为 O(n),因为我们仅进行了两次线性遍历。这是相对优化的,因为我们需要至少一次遍历来根据评分分配糖果。
3. 代码实现
#include <stdio.h>
#include <stdlib.h>

int candy(int* ratings, int ratingsSize) {
    if (ratingsSize == 0)
        return 0;

    int *candy = (int*)malloc(sizeof(int) * ratingsSize);
    for (int i = 0; i < ratingsSize; i++)
        candy[i] = 1;
    
    // 从左向右
    for (int i = 1; i < ratingsSize; i++) {
        if (ratings[i] > ratings[i - 1])
            candy[i] = candy[i - 1] + 1;
    }

    // 从右向左
    for (int i = ratingsSize - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i + 1])
            candy[i] = (candy[i] > candy[i + 1] + 1) ? candy[i] : candy[i + 1] + 1;
    }

    int totalCandy = 0;
    for (int i = 0; i < ratingsSize; i++)
        totalCandy += candy[i];

    free(candy);
    return totalCandy;
}

int main() {
    int ratings[] = {1, 0, 2};
    int size = sizeof(ratings) / sizeof(ratings[0]);
    printf("Minimum candies needed: %d\n", candy(ratings, size));
    return 0;
}
4. 总结

这个题目主要考查数组的遍历和条件比较。通过这种类型的题目,可以加深对数组操作和逻辑比较的理解。为了提升解题能力,可以多练习类似的数组和贪心算法问题。通过不断练习,可以提高对问题的理解和解决问题的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值