Problem:
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?
Algorithm:
方法一:回溯法。
根据条件,每个孩子至少得到一块糖。所以,如果要得到最优解知道给每个评价最低的孩子(ratings的极小元)一块糖。然后,从这个极小点向回(后)分配糖。在这道题里,只有rating高(至少1)才能得到更多的糖。所以,如果两个人的rating相同,那么第二个人就只需要给一块糖就可以了。如此把所有孩子的糖分配完毕就可以了。
2. There is no comparements if the peak is at 0 or len-1.
Solutions:
C++:
int candy(vector<int> &ratings) {
int len=ratings.size();
if(len==0) return 0;
if(len==1) return 1;
vector<int> candy(len, 0);
int peak=0, bottom=0;
bool touchEnd=false;
for(int start=0; start<len-1;){
//Iterate from the zero pos to the last one.
if(ratings[start]<=ratings[start+1]){
//Asending sunseq.
candy[start]=1;
for(int j=start+1; j<len; ++j){
if(ratings[j]>ratings[j-1]){
candy[j]=candy[j-1]+1;
}else if(ratings[j]==ratings[j-1]){
candy[j]=1;
}else{
peak=j-1;
break;
}
if(j==len-1) touchEnd=true;
}
}
if(touchEnd) break;
//Find the next local min rating.
for(int k=peak+1; k<len; ++k){
if(ratings[k]>ratings[k-1]){
bottom=k-1;
break;
}
if(k==len-1) bottom=k;
}
//Assign the amount of candies in a backtracking way.
candy[bottom]=1;
for(int k=bottom-1; k>peak; --k){
if(ratings[k]==ratings[k+1]) candy[k]=1;
else candy[k]=candy[k+1]+1;
}
//Reassign the amount of candies of the k-th child.
if(peak==0){
candy[peak]=candy[peak+1]+1;
}else if(peak==len){
candy[peak]=candy[peak-1]+1;
}else{
if(ratings[peak]>ratings[peak+1] && candy[peak]<=candy[peak+1]) candy[peak]=candy[peak+1]+1;
if(ratings[peak]>ratings[peak-1] && candy[peak]<=candy[peak-1]) candy[peak]=candy[peak-1]+1;
}
start=bottom;
}
int sum=0;
for(int i=0; i<len; ++i) sum+=candy[i];
return sum;
}