您的位置:首页 > 其它

LeetCode(135) Candy

2015-01-20 10:40 435 查看
题目如下:

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?

分析如下:

开出一个O(n)大小的数组,用来记录每个小孩的那糖数,因为每个小孩至少要拿1颗糖,所以数组元素初始化为1.

case 1. 假设有小孩A, B , rating分别是{1,1},显然每个人各拿1颗糖就够,显然每个人拿糖颗数是{1, 1},最后答案为2.

case 2. 假设有小孩A, B, C, D, rating分别是{10, 32, 43, 55}, 那么每个人拿糖的颗数依次为{1, 2, 3, 4},最后答案为10. 这说明可以顺序扫描数组,找到一个递增序列,拿糖数从1开始递增。比如这里找到了递增序列A, B, C, D, 拿糖数从A = 1开始依次递增。

case3. 假设有小孩A, B ,C ,D E, F, rating 分别是{10, 32, 43, 55, 40, 11}, 那么每个人拿糖颗数是 {1, 2, 3, 4, 2, 1}, 这说明可以在顺序扫描数组之后,再反序扫描数组,得到反序扫描数组时的递减序列。比如顺序扫描了A, B ,C, D, E, F之后,得到{1, 2, 3, 4, 1, 1,},之后再反序扫描数组,找寻递增数列,每段递增数列的拿糖颗数也从1开始递增。反序扫到F,得到F=1, 扫到E 因为E> F, 所以E = 2。扫到D,因为D>
E ,所以D= 3,但是其实这里的D和E, F不一样,D是之前顺序扫描时候已经被赋值过的值,D= 4,而反序扫描的时候,

D= 3, 显然只能取大值才能满足要求。所以反序扫描的时候,如果遇到已经在顺序扫描中赋值的小孩,要两个值中取较大的值。

上面描述的是贪心算法的思想。

我的代码:

//38ms
class Solution {
public:
    int candy(vector<int> &ratings) {
        if (ratings.size() <= 1) return 1;
        
        int sum = 0;
        vector<int> assign(ratings.size(), 1);
        
        for (int i = 1; i < assign.size(); ++i) {
            if (ratings[i] > ratings[i - 1]) {
                if (assign[i-1] + 1 > assign[i]) {
                    assign[i] = assign[i-1] + 1;
                }
            }
        }
        
        for (int i = assign.size() - 2; i >= 0; --i) {
            if (ratings[i] > ratings[i + 1]) {
                if (assign[i+1] + 1 > assign[i]) {
                    assign[i] = assign[i+1] + 1;
                }
            }
        }
        
        for (int i = 0; i < assign.size(); ++i)
            sum += assign[i];
        return sum;
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: