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?
思路:
rating的趋势无非三种,上升,不变,下降。上升的话,无论上升多少rating,都加一块糖就好了。题目默认不变情况下,糖数无需满足升降趋势,因此可以按照尽量少的方式给。下降的话就不好说了。因为下降到一定程度就可能有人分不到糖了,没准还要倒贴,只好提高下降趋势发生之前的那个人的糖数。
题解:
class Solution {
public:
struct trend_t
{
char trend;
int len;
};
int candy(const vector<int>& ratings)
{
auto nsum = [](const int n)->int { return n * (n + 1) / 2; };
const auto SIZE = ratings.size();
// special condition
if (SIZE == 0)
return 0;
else if (SIZE == 1)
return 1;
vector<trend_t> trend;
trend.push_back({'-', 1});
int prev_rate = ratings[0];
for (auto i = 1; i < SIZE; ++i)
{
int curr_rate = ratings[i];
char tr = curr_rate > prev_rate ? '+' :
(curr_rate == prev_rate ? '=' : '-');
if (trend.back().trend != tr)
trend.push_back({tr, 1});
else
++trend.back().len;
prev_rate = curr_rate;
}
// analyze the trend
int total_candy = nsum(trend[0].len);
int last_candy = 1;
for (auto i = 1; i < trend.size(); ++i)
{
if (trend[i].trend == '+')
{
total_candy += nsum(trend[i].len) + last_candy * trend[i].len;
last_candy += trend[i].len;
}
else if (trend[i].trend == '=')
{
total_candy += trend[i].len;
last_candy = 1;
}
else
{
if (last_candy > trend[i].len)
total_candy += nsum(trend[i].len);
else
total_candy += nsum(trend[i].len) + (trend[i].len + 1 - last_candy);
last_candy = 1;
}
}
return total_candy;
}
};