Skip to content

Commit cb32b25

Browse files
committed
feat: 135.分发糖果
1 parent 3dcfb16 commit cb32b25

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@
257257

258258
#### 贪心拓展题目
259259

260+
- [x] [135.分发糖果](./topics/greedy/ext-candy.md)
260261
- [x] [455.分发饼干](./topics/greedy/ext-assign-cookies.md)
261262

262263
## 其他

topics/greedy/ext-candy.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# 135. 分发糖果
2+
3+
https://leetcode-cn.com/problems/candy/
4+
5+
- [135. 分发糖果](#135-分发糖果)
6+
- [题目描述](#题目描述)
7+
- [方法 1:贪心](#方法-1贪心)
8+
- [思路](#思路)
9+
- [复杂度分析](#复杂度分析)
10+
- [代码](#代码)
11+
12+
## 题目描述
13+
14+
```
15+
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
16+
17+
你需要按照以下要求,帮助老师给这些孩子分发糖果:
18+
19+
每个孩子至少分配到 1 个糖果。
20+
相邻的孩子中,评分高的孩子必须获得更多的糖果。
21+
那么这样下来,老师至少需要准备多少颗糖果呢?
22+
23+
示例 1:
24+
25+
输入: [1,0,2]
26+
输出: 5
27+
解释: 你可以分别给这三个孩子分发 2、1、2 颗糖果。
28+
示例 2:
29+
30+
输入: [1,2,2]
31+
输出: 4
32+
解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。
33+
第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
34+
35+
来源:力扣(LeetCode)
36+
链接:https://leetcode-cn.com/problems/candy
37+
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
38+
```
39+
40+
## 方法 1:贪心
41+
42+
### 思路
43+
44+
- 根据题意,对于每个孩子,我们只需要考虑他左右两侧的孩子。
45+
- 因为要准备 `尽量少` 的糖果,所以,我们只在当前孩子比左右孩子分数高的时候,才给他更多糖果。
46+
- 分两次遍历数组,第一次只考虑每个孩子左边的孩子,第二次只考虑每个孩子右边的孩子(左右顺序不重要,也可以先考虑右边再考虑左边)。
47+
48+
### 复杂度分析
49+
50+
- 时间复杂度:$O(N)$。
51+
- 空间复杂度:$O(N)$。
52+
53+
### 代码
54+
55+
JavaScript Code
56+
57+
```js
58+
/**
59+
* @param {number[]} ratings
60+
* @return {number}
61+
*/
62+
var candy = function (ratings) {
63+
if (!ratings || !ratings.length) return 0;
64+
65+
// 每个孩子都有至少一颗糖果
66+
const candies = Array(ratings.length).fill(1);
67+
68+
// 先考虑每个孩子左边的孩子,如果他比左边的分数高,就把他的糖果改成左边孩子糖果+1
69+
for (let i = 1; i < ratings.length; i++) {
70+
// 因为初始糖果数都是 1,所以 candies[i] <= candies[i - 1] 这个判断条件就没必要啦
71+
if (ratings[i] > ratings[i - 1]) candies[i] = candies[i - 1] + 1;
72+
}
73+
74+
// 再考虑每个孩子右边的孩子,如果他比右边的分数高,而且他的糖果比右边的少,
75+
// 就将他的糖果数在右边孩子糖果的基础上加一
76+
for (let i = ratings.length - 2; i >= 0; i--) {
77+
if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1])
78+
candies[i] = candies[i + 1] + 1;
79+
}
80+
81+
// 求和
82+
return candies.reduce((a, b) => a + b, 0);
83+
};
84+
```
85+
86+
Python Code
87+
88+
```py
89+
class Solution(object):
90+
def candy(self, ratings):
91+
"""
92+
:type ratings: List[int]
93+
:rtype: int
94+
"""
95+
candies = [1] * len(ratings)
96+
97+
# 考虑每个孩子的左边
98+
for i in range(1, len(ratings)):
99+
if ratings[i] > ratings[i - 1]:
100+
candies[i] = candies[i - 1] + 1
101+
102+
# 考虑每个孩子的右边
103+
for i in range(len(ratings) - 2, -1, -1):
104+
if ratings[i] > ratings[i + 1] and candies[i] <= candies[i + 1]:
105+
candies[i] = candies[i + 1] + 1
106+
107+
return sum(candies)
108+
```

0 commit comments

Comments
 (0)