Featured image of post Candy

Candy

135. 分发糖果

分析

  1. 递归+记忆化搜索:

    • 使用一个数组 candy 记录每个孩子应该分到的糖果数,初始值全为 1
    • 对于每个孩子,递归判断左右相邻的孩子评分关系,更新糖果数量。
  2. 记忆化优化:

    • 如果某个孩子的糖果数已计算过 candy[i] != 1,直接返回,避免重复计算
  3. 左右两侧递归更新:

    • 如果左边孩子评分比当前孩子低,则当前孩子糖果数应该比左边多 1
    • 如果右边孩子评分比当前孩子低,则当前孩子糖果数应该比右边多 1
  4. 累加结果:

    • 遍历所有孩子,将糖果总数累加得到最少糖果数

时间复杂度

时间复杂度 O(n)

空间复杂度

空间复杂度为 O(n)

C++代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution
{
public:
    int candy(vector<int>& ratings)
    {
        int n = ratings.size();
        std::vector<int> candy(n, 1);  // 初始化每个孩子分 1 个糖果

        int res = 0;
        for (int i = 0; i < n; ++i)
            res += minCandy(ratings, candy, i);  // 递归更新糖果数

        return res;  // 返回总糖果数
    }

    // 递归函数:计算第 child 个孩子最少需要的糖果数
    int minCandy(std::vector<int>& ratings, std::vector<int>& candy, int child)
    {
        if (candy[child] != 1)  // 如果已计算过,直接返回
            return candy[child];

        // 左边孩子评分更低,当前孩子糖果+1
        if (child > 0 && ratings[child - 1] < ratings[child])
            candy[child] = std::max(candy[child], minCandy(ratings, candy, child - 1) + 1);

        // 右边孩子评分更低,当前孩子糖果+1
        if (child + 1 < ratings.size() && ratings[child] > ratings[child + 1])
            candy[child] = std::max(candy[child], minCandy(ratings, candy, child + 1) + 1);

        return candy[child];  // 返回计算结果
    }
};
Built with Hugo
Theme Stack designed by Jimmy