分糖果问题 与 扩展(修改条件)
问题描述
一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:
- 每个孩子不管得分多少,起码分到一个糖果。
- 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果(若相同则无此限制)
给定一个数组 arr代表得分数组,请返回最少需要多少糖果。
要求: 时间复杂度为 O(n);空间复杂度为 O(n)
数据范围: 1≤n≤100000 ,1≤arr[i]≤1000
解题思路(贪心策略):
注意:若两个孩子得分相同,分配糖果无限制,即不需要保证分数相同(相邻与否),得到的糖果数相同
1、先创建一个长度为arr.length,元素都为1的数组
2、从左往右看:索引值从 0 到length-2,看arr[i] 与 arr[i+1]的关系,如果arr[i]
总结:从左往右,保证右边比左边大的时候,糖果数也大;从右往左,保证右边比左边大或相等的情况下,糖果数符合要求
代码:
import java.util.*;
import java.lang.Math;
public class Solution {
/**
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (int[] arr) {
// write code here
int len = arr.length;
if(len==1) return 0;
int[] candy = new int[len];
for(int i=0;iarr[i]){ //后一个分数更大
candy[i+1]=candy[i]+1; //多给个糖果
}
}
for(int i=len-1;i>0;i--){ //从右往左
if(arr[i-1]>arr[i]){ //前面分数大于后面的,保证前面的糖果数多余后一个的
candy[i-1]=Math.max(candy[i-1],candy[i]+1);
}
}
int res=0;
for(int i=0;i
扩展
上述分糖果题目中,对于分数相同的孩子,分得的糖果无限制,可多可少
现将条件2改成,任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果,且保证相邻的分数相同的孩子糖果数相同
思路
“从左往右看” 和 “从右往左看”时,添加分数相同的判断
代码
import java.util.*;
import java.lang.Math;
public class Solution {
/**
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (int[] arr) {
// write code here
int len = arr.length;
if(len==1) return 0;
int[] candy = new int[len];
for(int i=0;iarr[i]){ //后一个分数更大
candy[i+1]=candy[i]+1; //多给个糖果
}else if(arr[i+1]==arr[i]){ //分数相同
candy[i+1]=candy[i]; //后面与前面糖果数相同
}
}
for(int i=len-1;i>0;i--){ //从右往左
if(arr[i-1]>arr[i]){ //前面分数大于后面的,保证前面的糖果数多余后一个的
candy[i-1]=Math.max(candy[i-1],candy[i]+1);
}else if(arr[i-1]==arr[i]){
candy[i-1]=Math.max(candy[i-1],candy[i]);
}
}
int res=0;
for(int i=0;i