贪心算法

Posted 浮云神码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法相关的知识,希望对你有一定的参考价值。

今天分享LeetCode第135题,分糖果。题目如下:

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


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


    每个孩子至少分配到 1 个糖果。

    评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。

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



根据题意:评分更高的孩子必须比他两侧邻位的孩子分的糖果更多,多几个呢?至少多一个。

假设评分为一个递增序列,第一个孩子分1颗糖果, 第二个孩子分2颗糖果,... 第N个孩子分N颗糖果,我们很容易就计算出糖果的总数。

假设评分为一个递减序列,该怎么分配呢?假设还是上面的分配方式,第一个孩子分1颗糖果,第二个孩子要比第一个孩子分的少,最少也要分1颗,这就产生了矛盾,我们需要调整分给第一个孩子的糖果,分给第一个小朋友2颗,第二个小朋友1颗。那么第三个小朋友呢?我们又需要再调整前两个小朋友分的糖果。好麻烦... 反向思考一下:从最后一个孩子开始分糖果。第N个小朋友分1个,第N-1个小朋友分2个, 第i个小朋友分N+1-i个,第1个小朋友分N个。这正是按递增序列进行分配的结果。

在评分记录中,一会是递增序列,一会是递减序列,对于这两种情况,我们从左向右处理递增序列,从右向左处理递减序列,最终取两者之间的较大值作为结果,满足评分更高的孩子必须比他两侧邻位的孩子分的糖果更多


/** * https://leetcode-cn.com/problems/candy * 135. 分发糖果 * 难度 困难 * 老师想给孩子们分发糖果,有 N个孩子站成了一条直线, * 老师会根据每个孩子的表现,预先给他们评分。 * <p> * 你需要按照以下要求,帮助老师给这些孩子分发糖果: * <p> * 每个孩子至少分配到 1 个糖果。 * 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。 * 那么这样下来,老师至少需要准备多少颗糖果呢? * <p> * 示例1: * 输入:[1,0,2] * 输出:5 * 解释:你可以分别给这三个孩子分发 2、1、2 颗糖果。 * <p> * 示例2: * 输入:[1,2,2] * 输出:4 * 解释:你可以分别给这三个孩子分发 1、2、1 颗糖果。 * 第三个孩子只得到 1 颗糖果,这已满足上述两个条件。 * <p> * 来源:力扣(LeetCode) * 链接:https://leetcode-cn.com/problems/candy */public class Candy { public int candy(int[] ratings) { int sum = 0; int n = ratings.length; // 基于贪心原则, 每个小朋友只分一个糖果 int[] candies = new int[n]; // 基于贪心算法, 毫无疑问, 第一个小朋友分一个就够了 candies[0] = 1; // 从前向后遍历, 只对当前评分大于前一个评分的情况进行处理 // 满足条件: 当我比左边小朋友评分高的话, 我的糖果比他多1个 // rating[i + 1] = rating[i] + 1; for (int i = 1; i < n; i++) { if (ratings[i] > ratings[i - 1]) { candies[i] = candies[i - 1] + 1; } else { // 否则, 只分一个糖果 candies[i] = 1; } }
// 从后向前遍历, 只对当前评分大于后一个评分的情况进行处理 // 满足条件: 当我比右边小朋友评分高的话, 我的糖果比他多1个 // rating[i] = rating[i + 1] + 1; int[] candies2 = new int[n]; candies2[n - 1] = 1; for (int i = n - 2; i >= 0; i--) { if (ratings[i] > ratings[i + 1]) { candies2[i] = candies2[i + 1] + 1; } else { candies2[i] = 1; } }
// 对于第i个小朋友, 同时满足条件的话, 取两者中的最大值即可 for (int i = 0; i < n; i++) { sum += Math.max(candies[i], candies2[i]); } return sum; }}


以上是关于贪心算法的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法----区间覆盖问题(POJ2376)

Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|

贪心算法学习手册开放下载!!

贪心算法(各种贪心题目)

贪心算法-第一节:贪心算法概述

Matlab-贪心/贪婪算法