一些例子:
1 2 3 3 3 =》 8 因为candy数可以是
1 2 3 1 1
1 2 3 2 3 =》9 因为candy数可以是
1 2 3 1 2
思路:
1
- d[i] 是给第i个小孩最少几块糖
- rank[i] > rank[i - 1],必须比前一个多给一块,d[i] = d[i - 1] + 1
- rank[i] == rank[i - 1],两个排名一样,第二个就给一块就行了, d[i] = 1
- rank[i] < rank[i - 1],比上一个排名低,应该少给一块,但是若上一个已经只给一块了,就得往前推一个一个多给。推到什么时候为止呢?若排名比下一个高,糖还一样多,就得再给;直到这个关系打破(排名一样或比下一个还低,或是糖已经满足关系)就不用再往前推了。
或者
- use store[] to store the kid's candy result
- give first kid[0] candy
- start loop : from index 1 to n
- if the ratings[i] > ratings[i - 1], ascending order, just store[i] = store[i-1] + 1
- if ==, we can make it down to 1 (according to the condition)
- if the ratings[i] < ratings[i - 1], descending order, store[i] = 1;
- at the same time. we have to check if the store[i] == store[i-1] while ratings[i-1] is higher
- if so, make this previous store ++
- continue, check previous one, until find previous ratings is not high or previous store is not equal to the later one
- time (n^2) worst time is {6,5,4,3,2,1}
- space (n)
2 从左向右扫,再从右向左扫,这样就能满足题目的条件。在第二次扫描时顺便记录总共需要的candy数
http://joycelearning.blogspot.com/2013/10/leetcode-candy.html
http://blog.csdn.net/violet_program/article/details/12233949
package Level5;
/**
Candy
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?
*/
public class S145 {
public static void main(String[] args) {
int[] ratings = {5,3,1};
System.out.println(candy(ratings));
}
// O(n)
public static int candy(int[] ratings) {
int len = ratings.length;
if(len == 0){
return 0;
}
int min = len;
int[] candies = new int[len];
int cur = 0;
// 从第2个孩子扫描到结尾,比较每个孩子和他的左邻居
for(int i=1; i<len; i++){
if(ratings[i] > ratings[i-1]){
cur++;
}else{
cur = 0;
}
candies[i] = cur;
}
cur = 0;
// 从倒数第二个孩子扫描到第一个孩子,比较每个孩子和他的右邻居
for(int i=len-2; i>=0; i--){
if(ratings[i] > ratings[i+1]){
cur++;
}else{
cur = 0;
}
candies[i] = Math.max(candies[i], cur);
min += candies[i];
}
// 别忘了加上最后一个孩子的candy数
min += candies[len-1];
return min;
}
// O(n2) TLE
public static int candy2(int[] ratings) {
if(ratings.length == 0){
return 0;
}
int[] candies = new int[ratings.length];
candies[0] = 1;
for(int i=1; i<candies.length; i++){
if(ratings[i] > ratings[i-1]){
candies[i] = candies[i-1]+1;
}else if(ratings[i] == ratings[i-1]){
candies[i] = 1;
}else{
candies[i] = 1;
if(candies[i-1] == 1){
int j = i;
while(j > 0 && ratings[j-1]>ratings[j]){
candies[j-1]++;
j--;
}
}
}
}
int count = 0;
for(int val : candies){
count += val;
}
return count;
}
}