LeetCode_135_分发糖果
廖家龙 用心听,不照做

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:
1. 每个孩子至少分配到 1 个糖果。
2. 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。

那么这样下来,老师至少需要准备多少颗糖果呢?

示例:

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

输入:[1,2,2]
输出:4
解释:你可以分别给这三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这已满足上述两个条件。

解法1:贪心算法

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
//贪心策略:在每次遍历中,只考虑并更新相邻一侧的大小关系
class Solution {
public:
int candy(vector<int>& ratings) {

int size = ratings.size();

if (size < 2) return size;

vector<int> num(size,1); //定义一个长度为size的容器,num中每个值初始值都为1

//把所有孩子的糖果数初始化为1,先从左到右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的糖果数加1;再从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数加1
for (int i = 1;i < size;++i) {
if (ratings[i] > ratings[i - 1]) num[i] = num[i - 1] + 1;
}

for (int i = size - 1;i > 0;--i) {
if (ratings[i] < ratings[i - 1]) num[i - 1] = max(num[i - 1],num[i] + 1);

//注意不可以这样写:[1,3,4,5,2]
//if (ratings[i] < ratings[i - 1]) num[i - 1] = num[i] + 1;
}

//accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。 accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。
return accumulate(num.begin(),num.end(),0); //求和
}
};