Leetcode 135.Candy

Leetcode 135.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?

Example 1:

Input: [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.

Example 2:

Input: [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
             The third child gets 1 candy because it satisfies the above two conditions.

解法:

这个题的意思大概是在给定优先级的孩子序列里,求出需要分发出去的糖的最小数目,且优先级的孩子要比相邻优先级小的孩子获得的糖多,举个例子:

例如:现在孩子的优先级为{1,2,3,4,2,1}

注:由于要让总糖数最小且每个孩子必须要有一颗糖,所以我们可以初始化将每一个孩子需要的糖数都设为 1,且优先级大的每次递增 1

从第一个孩子开始:

  • 第 1 个孩子优先级为 1 ,需要的糖数为 1
  • 第 2 个孩子优先级为 2 ,其优先级大于第 1 个孩子,所以需要的糖数为 1 + 1 = 2
  • 第 3 个孩子优先级为 3 ,其优先级大于第 2 个孩子,所以需要的糖数也为 2 +1 = 3
  • 第 4 个孩子优先级为 4 ,其优先级大于第 3 个孩子,所以需要的糖数为 3 + 1 = 4

下面问题就出现了:

如果我们按照刚才的算法继续从左往右算的话,那么第 5 个孩子跟第 6 个孩子得到的糖数都会为 1 ,但是这是不对的,因为第 5 个孩子的优先级要大于第 6 个孩子,所以我们需要

当从左往右扫描完毕之后,再从右往左进行一次上面的操作,也即如果后一个孩子比前一个孩子优先级低,那么前一个孩子在后一个孩子的糖数上加一

那么从后往前算:

  • 第 6 个孩子优先级为 1 ,需要的糖数为 1
  • 第 5 个孩子优先级为 2 ,其优先级大于第 6 个孩子,所以需要的糖数为 1 + 1 = 2
  • 第 4 个孩子优先级为 4 ,其优先级大于第 5 个孩子,所以需要的糖数为 2 + 1 = 3

这里就又出现矛盾了,我们第一次遍历从左往右算的时候,第四个孩子已经分到了 4 颗糖果,现在从右往左算的时候,反而第四个孩子的糖果数目变少了,这是不对的,所以我们在进行完从左往右搜索遍历之后进行从右往左遍历时候,需要递增candy[y-1]的时候,可以判断一下 candy[y] +1 与 candy[y-1]的大小,选用其中比较大的一个数字。


代码:

class Solution {
public:
    int candy(vector<int>& ratings) {
        int a[ratings.size()] = {0} ;
        //初始化candy序列
        for(int i = 0 ; i < ratings.size() ; i ++ )
        {
            a[i] = 1 ;
        }
        //从左往右搜
        for(int i = 0 ; i < ratings.size() -1 ; i ++)
        {
            if(ratings[i]<ratings[i+1])
            {
                a[i+1] = a[i] + 1 ;
            }
        }
        //从右往左搜
        for(int i = ratings.size()-1 ; i >=1 ; i -- )
        {
            if(ratings[i-1] > ratings[i] )
            {
                a[i-1] = max( a[i-1] , a[i] + 1 ) ;
            }
        }
        int total = 0 ;
        for(int i = 0 ; i < ratings.size() ; i ++ )
        {
            total = total + a[i] ;
        }
        return total ;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值