
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LaputaFallen/article/details/79967444
Description
There are N children standing in a line. Each child is assigned a rating value.
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.
What is the minimum candies you must give?
问题描述
有N个孩子站成一条线。每个孩子都有对应的分值。
你在分配给孩子们糖时需满足如下约束:
- 每个孩子至少分配一颗糖
- 高分数的孩子比旁边低分数的孩子拿的糖要多
问题分析
维护两个数组,leftToRight,RightToLeft
第一次从左往右遍历,若nums[i] > nums[i - 1],那么leftToRight[i] = leftToRight[i - 1] + 1
第二次从右往左遍历,若nums[i] > nums[i + 1],那么rightToLeft[i] = rightToLeft[i + 1] + 1
第三次从左往右遍历,sum += Math.max(leftToRight[i], RightToLeft[i])
还可以对这个算法优化一下
将leftToRight,RightToLeft合并为一个数组,dp
在第二次遍历的时候,只有当值需要更新的时候会更新(新的值比当前值大)
解法1
class Solution {
public int candy(int[] ratings) {
int len = ratings.length;
int[] leftToRight = new int[len];
int[] rightToLeft = new int[len];
Arrays.fill(leftToRight, 1);
Arrays.fill(rightToLeft, 1);
for(int i = 1;i < len;i++){
if(ratings[i] > ratings[i - 1]) leftToRight[i] = leftToRight[i - 1] + 1;
}
for(int i = len - 2;i >= 0;i--){
if(ratings[i] > ratings[i + 1]) rightToLeft[i] = rightToLeft[i + 1] + 1;
}
int sum = 0;
for(int i = 0;i < len;i++) sum += Math.max(leftToRight[i], rightToLeft[i]);
return sum;
}
}
解法2
class Solution {
public int candy(int[] ratings) {
int len = ratings.length;
int[] dp = new int[len];
Arrays.fill(dp, 1);
for(int i = 1;i < len;i++){
if(ratings[i] > ratings[i - 1]) dp[i] = dp[i - 1] + 1;
}
int sum = dp[len - 1];
for(int i = len - 2;i >= 0;i--){
if(ratings[i] > ratings[i + 1]){
dp[i] = Math.max(dp[i], dp[i + 1] + 1);
}
sum += dp[i];
}
return sum;
}
}