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?
分析:要求里面只是限制了rating高的children比低的蜡烛要多,而对rating相同的相邻children没有要求,故其可以设置为尽量的合理的低。
如rating[ 1,2,3,3,3,3,2,1]则中间rating为3的可以蜡烛数为1而不违反要求。
方法是递增序列则蜡烛数每次加1,而用一个栈存储递减序列,在对其反向递增加1,若两者有重合的则选取较大值。之间如果有未处理的即为rating相等的非边界children。最后将其全部设置为1;
class Solution{
public:
int candy( vector<int> &ratings ) {
if( ratings.empty() ) return 0;
int n = ratings.size();
if( n == 1 ) return 1;
int i = 1;
int *p = new int[ratings.size()]; // 存储每个小孩的蜡烛数
for( int i = 0;i < n;++i )
p[i] = 0;
stack<int> stk;
while( true ) {
int count = 1;
int flag = 0;
while( ratings[i] == ratings[i-1] ) ++i; //跳过相等点
while( ratings[i] > ratings[i-1] && i < n) {
flag = 1;
p[i-1] = count++;
++i;
}
if( flag ) {
p[i-1] = ( ratings[i-1] == ratings[i-2] ? p[i-2] : p[i-2] + 1 );
flag = 0;
}
if( i == n ) break;
while( ratings[i] == ratings[i-1] ) ++i;
while( ratings[i] < ratings[i-1] && i < n) {
flag = 1;
stk.push( i-1 );
++i;
}
if( flag )
stk.push( i - 1 );
count = 1;
while( !stk.empty() ) {
int temp = stk.top();
stk.pop();
if( stk.empty() )
p[temp] = p[temp] > count ? p[temp] : count; //重合位置取较大值
else
p[temp] = count++;
}
if( i == n ) break;
}
int sum = 0;
for( int i = 0;i < n;++i ) {
if( p[i] == 0 ) p[i] = 1;<span style="white-space:pre"> </span>//对未赋值的内部相等点赋值1
sum += p[i];
}
return sum;
}
};