135.分发糖果
- 本题涉及到一个思想,就是处理好一边再处理另一边,不要两边想着一起兼顾。也就是说递增递减都要处理的情况,需要遍历两遍。后面还会有题目用到这个思路。
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
提示:
- n == ratings.length
- 1 <= n <= 2 * 10^4
- 0 <= ratings[i] <= 2 * 10^4
思路
本题大致思路如下图所示。注意,因为只给出了两个条件,没有说数值相等的情况,因此数值相等,又没有比左右评分高的情况,只需要基础的1就可以了。
本题,因为是相邻的孩子作比较,我们需要同时考虑两边的情况,也就是考虑左边的小孩和右边的小孩。
这种需要同时考虑两边的情况,例如同时需要比较左边小孩+右边小孩,一定要先确定一边,再确定另一边!也就是说需要把一边的情况全部确认完毕,再去确认另一边。两边一起比较一定会乱!
每个小孩既要和左边比较,又要和右边比较,此时首先确定一边,也就是右边小孩>左边小孩的情况。左边小孩>右边的情况,我们先不管。
第一种情况:右>左
右孩子>左孩子的情况:
这种情况,首先考虑极端情况,也就是一路都是右边>左边。这样的话,糖果的数量是从左到右累积,因此遍历也需要从左往右遍历。
//判断逻辑
if(rating[i]<rating[i+1]){
candy[i+1]=candy[i]+1;
}
第二种情况:左>右(倒序遍历)
左孩子>右孩子的情况如图所示。注意,左>右这种情况需要从后往前遍历。
原因是,由于本题相邻孩子,评分更高会获得更多糖果,因此我们需要考虑极端情况,也就是一路上都是左>右的情况。
如果一路上都是左>右的情况,那么糖果的数目需要从后向前累积!也就是说,我们必须采用倒序遍历,才能接收到左孩子>右孩子的累积结果。
两种情况的结果合并,通过取最大值
第二种情况还有一个需要注意的问题,就是到了第二种情况的时候,candy[i]已经有第一种情况的数值了。此时,为了满足既要比较左边,又要比较右边,需要对两个方法得到的candy[i]取最大值。取最值的逻辑如下图:
绿色字体是第二个例子中,以右>左规则来遍历的结果。由此可见需要的操作是取max值。
//判断逻辑