[LeetCode] 135. Candy

There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

Return the minimum number of candies you need to have to distribute the candies to the children.

Example 1:

Input: ratings = [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.

Example 2:

Input: ratings = [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
The third child gets 1 candy because it satisfies the above two conditions.

Constraints:

  • n == ratings.length
  • 1 <= n <= 2 * 104
  • 0 <= ratings[i] <= 2 * 104

分发糖果。

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

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

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/candy
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是贪心。根据题意,我们需要对input数组扫描两遍,因为对于每个孩子来说,他拥有的糖果数需要同时和他的左右邻居比较以确保满足题意。所以我们创建两个和 input 数组等长的数组,left 数组从左往右扫描,right 数组从右往左扫描。

更新 left 数组的方式是,对于每个孩子,需要看他的评分是否大于他左边的孩子的评分,如果大于,当前这个孩子的糖果数起码是他左边孩子的糖果数 + 1

更新 right 数组的方式是,对于每个孩子,需要看他的评分是否大于他右边的孩子的评分,如果大于,当前这个孩子的糖果数起码是他右边孩子的糖果数 + 1

在更新 right 数组的同时,我们可以得到相同位置上 left 数组和 right 数组之间的较大值,这个较大值即是当前位置上的孩子需要拥有的糖果数

最后附上一个动图帮助理解。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int candy(int[] ratings) {
 3         int[] left = new int[ratings.length];
 4         int[] right = new int[ratings.length];
 5         Arrays.fill(left, 1);
 6         Arrays.fill(right, 1);
 7         for (int i = 1; i < ratings.length; i++) {
 8             if (ratings[i] > ratings[i - 1]) {
 9                 left[i] = left[i - 1] + 1;
10             }
11         }
12         int count = left[ratings.length - 1];
13         for (int i = ratings.length - 2; i >= 0; i--) {
14             if (ratings[i] > ratings[i + 1]) {
15                 right[i] = right[i + 1] + 1;
16             }
17             // 同时满足左规则和右规则的数量,是当前位置所需的糖果数量
18             count += Math.max(left[i], right[i]);
19         }
20         return count;
21     }
22 }

 

LeetCode 题目总结

posted @ 2020-11-03 13:59  CNoodle  阅读(425)  评论(0编辑  收藏  举报