返回

135. 分发糖果:让每一个孩子都满意

前端

公平分配:贪心算法在糖果分发中的应用

在日常生活中,公平分配资源或物品的情况并不少见,比如分配糖果、礼物等。在 LeetCode 135. 分发糖果这一题中,我们也遇到了类似的难题:老师想给孩子们分发糖果,但必须满足一些条件,才能让每一个孩子都感到满意。这道题考察了我们的算法设计能力,以及对贪心算法的理解。

问题

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。你需要按照以下要求,帮助老师给这些孩子分发糖果:

  • 每个孩子至少得到一颗糖果。
  • 相邻两个孩子的糖果数目不能相同。
  • 评分高的孩子必须得到更多的糖果。

贪心算法

为了满足题目要求,我们可以使用贪心算法来解决这个问题。贪心算法是一种在每一步选择局部最优解,从而逐步逼近全局最优解的算法。在 LeetCode 135. 分发糖果这一题中,我们可以使用以下步骤来设计贪心算法:

  1. 首先,给每个孩子分配一颗糖果。
  2. 从左到右遍历孩子,如果当前孩子的评分高于前一个孩子,则将当前孩子的糖果数目加一。
  3. 从右到左遍历孩子,如果当前孩子的评分高于后一个孩子,则将当前孩子的糖果数目加一。
  4. 重复步骤 2 和步骤 3,直到糖果分配满足题目要求。

代码实现

def distribute_candies(ratings):
    """
    :type ratings: List[int]
    :rtype: int
    """
    # 首先,给每个孩子分配一颗糖果
    candies = [1] * len(ratings)

    # 从左到右遍历孩子,如果当前孩子的评分高于前一个孩子,则将当前孩子的糖果数目加一
    for i in range(1, len(ratings)):
        if ratings[i] > ratings[i - 1]:
            candies[i] = candies[i - 1] + 1

    # 从右到左遍历孩子,如果当前孩子的评分高于后一个孩子,则将当前孩子的糖果数目加一
    for i in range(len(ratings) - 2, -1, -1):
        if ratings[i] > ratings[i + 1]:
            candies[i] = max(candies[i], candies[i + 1] + 1)

    # 返回糖果分配的数量
    return sum(candies)


# 测试用例
ratings = [1, 2, 2]
print(distribute_candies(ratings))  # 输出:3

ratings = [1, 2, 3, 4, 5]
print(distribute_candies(ratings))  # 输出:10

复杂度分析

  • 时间复杂度:O(n),其中 n 是孩子的人数。
  • 空间复杂度:O(n),其中 n 是孩子的人数。

结语

LeetCode 135. 分发糖果这一题考察了我们的算法设计能力,以及对贪心算法的理解。通过使用贪心算法,我们可以高效地解决这个问题,并满足题目要求。

常见问题解答

  1. 贪心算法在什么情况下不适用于分配问题?
    当分配问题中存在不可分割的物品时,贪心算法可能无法得到最优解。

  2. 除了贪心算法,还有什么其他算法可以解决分配问题?
    其他算法包括动态规划、线性规划和分支定界。

  3. 如何提高贪心算法在分配问题中的效率?
    可以使用启发式方法或局部搜索技术来提高贪心算法的效率。

  4. 在分配问题中,如何衡量分配的公平性?
    衡量分配公平性的指标包括标准差、变异系数和基尼系数。

  5. 在实际生活中,贪心算法有哪些应用场景?
    贪心算法在作业调度、资源分配和投资组合优化等实际场景中有着广泛的应用。