LeetCode题解:Candy

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;
}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值