leetcode-135:分发糖果

简介: leetcode-135:分发糖果

题目

题目链接

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。

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

示例 1:

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

示例 2:

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

解题

方法一:贪心

这在leetcode上是一道困难的题目,其难点就在于贪心的策略,如果在考虑局部的时候想两边兼顾,就会顾此失彼。

那么本题采用了两次贪心的策略:

  • 一次是从左到右遍历,只比较右边孩子评分比左边大的情况。
  • 一次是从右到左遍历,只比较左边孩子评分比右边大的情况。

这样从局部最优推出了全局最优,即:相邻的孩子中,评分高的孩子获得更多的糖果。

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(),1);
        for(int i=1;i<ratings.size();i++){
            if(ratings[i]>ratings[i-1]) candyVec[i]=candyVec[i-1]+1;
        }
        for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]) candyVec[i]=max(candyVec[i],candyVec[i+1]+1);
        }
        int res=0;
        for(int num:candyVec) res+=num;
        return res;
    }
};

对于从右边开始遍历的时候,如果candyVec[i]>candyVec[i+1]+1 ,说明本来就已经满足条件了,不需要更改

max(candyVec[i],candyVec[i+1]+1)此时就为candyVec[i]

因此可以先遍历左边,再遍历右边的方式

for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]) candyVec[i]=max(candyVec[i],candyVec[i+1]+1);
        }

关于求和

可以使用

return accumulate(candyVec.begin(),candyVec.end(),0);

accmulate(迭代器开头,迭代器末尾,初始数值);

换种写法

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n=ratings.size();
        vector<int> dp(n,1);
        for(int i=1;i<ratings.size();i++){
            if(ratings[i]>ratings[i-1]){
                dp[i]=dp[i-1]+1;
            }
        }
        for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                dp[i]=max(dp[i],dp[i+1]+1);
            }
        }
        return accumulate(dp.begin(),dp.end(),0);
    }
};

java

class Solution {
    public int candy(int[] ratings) {
        int n=ratings.length;
        int[] dp=new int[n];
        Arrays.fill(dp,1);
        for(int i=1;i<n;i++){
            if(ratings[i]>ratings[i-1]){
                dp[i]=Math.max(dp[i],dp[i-1]+1);
            }
        }
        for(int i=n-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                dp[i]=Math.max(dp[i],dp[i+1]+1);
            }
        }
        int sum=0;
        for(int i=0;i<n;i++){
            sum+=dp[i];
        }
        return sum;
    }
}

相关文章
|
9月前
|
Java
leetcode-455:分发饼干
leetcode-455:分发饼干
62 0
|
6月前
|
算法 Python
【Leetcode刷题Python】455.分发饼干
文章提供了解决LeetCode "分发饼干" 问题的Python实现代码,使用了排序和贪心算法。首先将孩子的胃口值和饼干的尺寸分别进行升序排序,然后通过双指针的方式遍历,尝试为每个孩子分配尺寸足够大的饼干,直到所有的孩子都得到满足或饼干分配完毕,返回满足的孩子数量的最大值。
28 2
|
8月前
|
存储 算法 数据可视化
如何使用多种算法解决LeetCode第135题——分发糖果问题
如何使用多种算法解决LeetCode第135题——分发糖果问题
|
8月前
|
算法
力扣经典150题第十五题:分发糖果
力扣经典150题第十五题:分发糖果
49 0
|
8月前
|
算法 机器人
【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人
【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人
|
9月前
|
索引
[经典力扣面试题]135. 分发糖果
[经典力扣面试题]135. 分发糖果
|
9月前
|
算法
leetcode代码记录(分发饼干
leetcode代码记录(分发饼干
53 0
|
9月前
leetcode:455. 分发饼干
leetcode:455. 分发饼干
43 0
|
9月前
|
算法 定位技术
六六力扣刷题贪心算法之分发饼干
六六力扣刷题贪心算法之分发饼干
69 0
|
5月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行