分发糖果
题目:
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。 那么这样下来,老师至少需要准备多少颗糖果呢?
示例1:
输入:[1,0,2] 输出:5 解释:你可以分别给这三个孩子分发 2、1、2 颗糖果。
示例2:
输入:[1,2,2] 输出:4 解释:你可以分别给这三个孩子分发 1、2、1 颗糖果。 第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
思路:
可以通过两次遍历,第一次从左往右遍历,当右边大于左边时,右边糖果数量为左边加1,满足右边是都符合条件。然后在倒着遍历,当左边大于右边时,同时糖果不多于右边,则左边糖果数量为右边加1,这样就满足了左边永远符合条件。即每次的操作都是满足一方符合条件。
cpp实现:
class Solution {
public:
int candy(vector<int>& ratings) {
int size = ratings.size();
if(size < 2) return size;
vector<int> cnt(size, 1);
for(int i = 1; i < size; i++){
if(ratings[i] > ratings[i-1])
cnt[i] = cnt[i-1] + 1;
}
for(int i = size - 1; i > 0; i--){
if(ratings[i-1] > ratings[i]){
cnt[i-1] = max(cnt[i-1], cnt[i] + 1);
}
}
return accumulate(cnt.begin(), cnt.end(), 0);
}
};
Java实现:
class Solution {
public int candy(int[] ratings) {
int size = ratings.length;
if(size < 2) return size;
int[] cnt = new int[size];
cnt[0] = 1;
for(int i = 1; i < size; i++){
if(ratings[i] > ratings[i-1]){
cnt[i] = cnt[i-1] + 1;
}else{
cnt[i] = 1;
}
}
for(int i = size - 1; i > 0; i--){
if(ratings[i-1] > ratings[i]){
cnt[i-1] = Math.max(cnt[i-1], cnt[i] + 1);
}
}
return IntStream.of(cnt).sum();
}
}
TypeScript实现:
function candy(ratings: number[]): number {
let size = ratings.length;
if(size < 2) return size;
let cnt: number[] = [1];
let sums: number = 0;
for(let i = 1; i < size; i++){
if(ratings[i] > ratings[i-1]){
cnt[i] = cnt[i-1] + 1;
}else{
cnt[i] = 1;
}
}
for(let i = size - 1; i > 0; i--){
if(ratings[i-1] > ratings[i]){
cnt[i-1] = Math.max(cnt[i-1], cnt[i] + 1);
}
sums += cnt[i];
}
return cnt[0] + sums;
};
|