有N个小朋友站在一排,每个小朋友都有一个评分
你现在要按以下的规则给孩子们分糖果:
- 每个小朋友至少要分得一颗糖果
- 分数高的小朋友要他比旁边得分低的小朋友分得的糖果多
你最少要分发多少颗糖果?
public class Solution { /*动态规划思想:每个糖果的值都要受限与邻居结点,如果评估值比邻居结点大,那么得到的糖果也比邻居结点多,因此都需要与左右邻居结点进行比较。*/ public int candy(int[] ratings) { if(ratings == null || ratings.length == 0) return 0; int len = ratings.length; int[] dp = new int[len]; int sum = 0; //初始化,给每个小朋友先分发一个糖果 for(int i = 0; i < len; i++){ dp[i] = 1; } //从左往右遍历,右边的小朋友分数比左边的小朋友分数高,则右边分数高的小朋友糖果+1 for(int i = 0; i < len -1; i++){ //和左邻居的比较 if(ratings[i+1] > ratings[i]) dp[i+1] = dp[i] + 1; } //从右往左遍历,左边的小朋友分数比右边的小朋友分数高,则左边分数高的小朋友糖果+1 for(int j = len - 2; j >= 0; j--){ //和右邻居的比较 if(ratings[j] > ratings[j+1] && dp[j] <= dp[j+1]) dp[j] = dp[j+1] + 1; } //计算总糖果数 for(int i = 0; i < len; i++){ sum += dp[i]; } return sum; } }
// 思路:遍历数组,给当前元素分配1, // 若前一个元素大于当前元素且其分配值小于等于当前的元素,则重新为其分配值为当前值+1,再次往前查看,直到不满足该条件 // 若当前值大于前一个值,则其分配值为前一个的值+1 public class Solution { public int candy(int[] ratings) { int sum = 0; int cur = 1; int res[] = new int[ratings.length]; for(int i = 0; i < ratings.length; i++) { res[i] = 1; int j = i; //不是第一个元素,且前一个元素大于当前元素,但其分配值不大于当前元素的分配值 while(j>=1 && ratings[j-1]>ratings[j] && res[j-1]<=res[j]) { res[j-1] = res[j] + 1; j--; } // 不是第一个元素且其值比前一个元素大,则为前一个元素的分配值加1 if(i>0 && ratings[i]>ratings[i-1]) res[i] = res[i-1] + 1; } for(int i = 0; i < res.length; i++) { sum += res[i]; } return sum; } }
用dp[i]记录前i个孩子的最小分配值。
用num[]记录目前糖果的分配情况。
从左到右遍历,有三种情况:
public static int candy(int[] ratings) {
int[] num = new int[ratings.length];
int[] dp = new int[ratings.length];
dp[0] = 1;
num[0] = 1;
for(int i=1;i<ratings.length;i++){
// 如果rating比前面一个小
if(ratings[i]<ratings[i-1]){
//如果前面一个孩子的糖果数为1,前面的要重新分配。
if(num[i-1]==1){
num[i-1]+=1;
for(int j=i-2;j>=0;j--){
if(ratings[j]>ratings[j+1]&&num[j]==num[j+1]){
num[j]=num[j]+1;
}else{
break;
}
}
for(int j=0;j<i;j++){
dp[i]+=num[j];
}
dp[i]+=1;
}else{
dp[i]=dp[i-1]+1;
}
num[i]=1;
}
// 如果rating与前面一个相等,那么这个孩子就分给他一个
if(ratings[i]==ratings[i-1]){
dp[i]=dp[i-1]+1;
num[i]=1;
}
// 如果rating比前面一个大,比前面一个多分一个
if(ratings[i]>ratings[i-1]){
dp[i]=dp[i-1]+num[i-1]+1;
num[i]=num[i-1]+1;
}
}
return dp[ratings.length-1];
}
import java.util.Arrays; public class Solution { public int candy(int[] ratings) { int len=ratings.length; if(ratings.length==0) return 0; int[] count=new int[len+1]; Arrays.fill(count, 1); //从左向右扫描 for(int i=1;i<len;i++){ if(ratings[i]>ratings[i-1]){ count[i]=count[i-1]+1; } } //从右向左扫描 for(int i=len-2;i>=0;i--){ if(ratings[i]>ratings[i+1]&&count[i]<=count[i+1]){ count[i]=count[i+1]+1; } } int sum=0; for(int i=0;i<len;i++){ sum+=count[i]; } return sum; } }
每次遇到降序从后往前更新到start为止
public class Solution {
public int candy(int[] rating) {
if(rating.length<=1) return rating.length;
int[] dp=new int[rating.length];
int start=0;
int sum=0;
dp[0]=1;
for(int i=1;i<rating.length;i++){
if(rating[i]>rating[i-1]){
dp[i]=dp[i-1]+1;
start=i;
}else if(rating[i]==rating[i-1]){
dp[i]=1;
start=i;
}else{
dp[i]=1;
for(int j=i-1;j>=start;j--){
if(dp[j]<=dp[j+1])
dp[j]=dp[j+1]+1;
}
}
}
for(int i=0;i<rating.length;i++){
sum+=dp[i];
}
return sum;
}
}
public int candy(int[] ratings) {
int result = 0;
int sum = ratings.length;
int candys[] = new int[sum];
//初始化,每个孩子一个糖果
for(int i=0;i<sum;i++){ candys[i] = 1; } //从左向右遍历,保证右边分数高的比左边的糖果多一个 for(int i=0;i<sum-1;i++){ if(ratings[i+1]> ratings[i]){
candys[i+1] = candys[i]+1;
}
}
//从右向左遍历,保证左边分数高的孩子,比右边的分数低的孩子至少多一块糖果
for(int i=sum-1;i>0;i--){
if(ratings[i-1] > ratings[i]){
candys[i-1] = Math.max(candys[i-1], candys[i]+1);
}
}
for(int i=0;i<sum;i++){
result+=candys[i];
}
return result;
}
public class Solution { public int candy(int[] ratings) { if (ratings == null || ratings.length == 0) return 0; int len = ratings.length; return candyNum(ratings, 0, 0); } public int candyNum(int[] ratings, int startIndex, int beforeCandyNum) { int len = ratings.length; if (startIndex >= len) return 0; if (startIndex == len - 1) return beforeCandyNum + 1; int curIndex = startIndex; while (curIndex < len - 1) { if (ratings[curIndex + 1] < ratings[curIndex]) { ++curIndex; } else break; } int nowCandyNum = 0; if (curIndex == startIndex) { nowCandyNum = beforeCandyNum + 1; } else { for (int i = curIndex; i >= startIndex; --i) { if (i == startIndex && curIndex - startIndex + 1 < beforeCandyNum + 1) { nowCandyNum += beforeCandyNum + 1; } else { nowCandyNum += curIndex - i + 1; } } } if (curIndex == len - 1) return nowCandyNum; else { if (ratings[curIndex + 1] == ratings[curIndex]) { return nowCandyNum + candyNum(ratings, curIndex + 1, 0); } else { if (curIndex == startIndex) return nowCandyNum + candyNum(ratings, curIndex + 1, nowCandyNum); else return nowCandyNum + candyNum(ratings, curIndex + 1, 1); } } } }
public class Solution { public int candy(int[] ratings) { if(ratings == null || ratings.length == 0) return 0; int sum = 0; int[] help = new int[ratings.length]; for(int i = 0; i < help.length; i++){ help[i] = 1; } for(int i = 1; i < ratings.length; ++i){ if(ratings[i] > ratings[i-1]){ help[i] = help[i-1] + 1; } } for(int i = ratings.length - 2; i >= 0; --i){ if(ratings[i] > ratings[i+1] && help[i] <= help[i+1]){ help[i] = help[i+1] + 1; } } for(int i = 0; i < help.length; i++){ sum += help[i]; } return sum; } }
public class Solution { public int candy(int[] ratings) { int len = ratings.length; if(len < 1) return 0; if(len == 1) return 1; boolean isOK = false; int[] candys = new int[len]; //糖果每个人初始化为1 for(int i = 0; i < len; i++){ candys[i] = 1; } int counts = 0; while(!isOK){ //遍历数组 判断当前孩子的rating是否比旁边的高 是的话糖果是否比旁边的少 是的话改变糖果值 //当遍历一遍 糖果值都没有改变的时候 说明分配完成 isOK = true; for(int i = 0; i < len; i++){ if(i == 0 ){ if(ratings[i] > ratings[i+1] && candys[i] <= candys[i+1]){ isOK = false; candys[i] = candys[i+1] + 1; //counts++; } } else if(i == len - 1){ if(ratings[i] > ratings[i-1] && candys[i] <= candys[i-1]){ isOK = false; candys[i] = candys[i-1] + 1; //counts++; } } else{ if(ratings[i] > ratings[i+1] && candys[i] <= candys[i+1]){ isOK = false; candys[i] = candys[i+1] + 1; //counts++; } if(ratings[i] > ratings[i-1] && candys[i] <= candys[i-1]){ isOK = false; candys[i] = candys[i-1] + 1; //counts++; } } } } for(int i = 0; i < len; i++){ counts += candys[i]; } return counts; } }
public class Solution { public int candy(int[] ratings) { if (ratings == null || ratings.length == 0) return 0; int total = 1, prev = 1, countDown = 0; for (int i = 1; i < ratings.length; i++) { if (ratings[i] >= ratings[i-1]) { if (countDown > 0) {
total += countDown*(countDown+1)/2; // arithmetic progression if (countDown >= prev) total += countDown - prev + 1;
countDown = 0;
prev = 1;
}
prev = ratings[i] == ratings[i-1] ? 1 : prev+1;
total += prev;
} else countDown++;
} if (countDown > 0) { // if we were descending at the end total += countDown*(countDown+1)/2; if (countDown >= prev) total += countDown - prev + 1;
} return total;
}
}
import java.util.*; public class Solution { public int candy(int[] ratings) { int[] arr1 = new int[ratings.length]; int[] arr2 = new int[ratings.length]; Arrays.fill(arr1, 1); Arrays.fill(arr2, 1); for (int i = 1; i < ratings.length; i ++) { if(ratings[i] > ratings[i - 1]) arr1[i] = arr1[i - 1] + 1; } for (int i = ratings.length - 1; i >= 1; i --) { if(ratings[i] < ratings[i - 1]) arr2[i - 1] = arr2[i] + 1; } int sum = 0; for (int i = 0; i < ratings.length; i ++) { sum += arr1[i] > arr2[i] ? arr1[i] : arr2[i]; } return sum; } }