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?
开始想到已扫描一遍,每次都看左右两边的邻居,比右边大,又加1了,还得看看是不是比做邻居糖果多了,如果ratings比左邻居小。还得不断再回溯比较左边。超时。
超时的算法:
int candy1(vector<int>& ratings) {
int n=ratings.size();
if(n==0) return 0;
int sum=0;
vector<int> candy(n,1);
for(int i=0;i<n;i++){
if(i>0&&ratings[i]>ratings[i-1]){//如果我的级别比前一个人的级别高,我就要比他多一个糖果。
candy[i]=candy[i-1]+1;
}
if(i<n-1&&ratings[i]>ratings[i+1]){//如果我的级别比后一个人高
if(candy[i]<=candy[i+1]){ candy[i]++;
//我就加一个,但是加完之后,可能出现一种情况是,前一个人比我级别高,我却和他一样多。
for(int j=i;ratings[j]<ratings[j-1]&&candy[j]>=candy[j-1]&&j>0;j--){
//那么我就给前一个同学加一个糖果
candy[j-1]++;//我还看前一个
}
}
}
}
for(int i=0;i<n;i++) sum+=candy[i];
return sum;
}
O(2n)的算法:从左到右,再从右到左扫描。每次只看一边的邻居。
int candy(vector<int>& ratings) {
int n=ratings.size();
if(n==0) return 0;
int sum=0;
vector<int> candy(n,1);
for(int i=1;i<n;i++){
if(ratings[i]>ratings[i-1]){//如果我的级别比前一个人的级别高,我就要比他多一个糖果。
candy[i]=candy[i-1]+1;
}
}
for(int i=n-2;i>=0;i--){
if(ratings[i]>ratings[i+1]){//如果我的级别比后一个人高
if(candy[i]<=candy[i+1]){
candy[i]=candy[i+1]+1;
}
}
}
for(int i=0;i<n;i++) sum+=candy[i];
return sum;
}