LeetCode 135. Candy

            大概题意:给一堆孩子发糖,孩子们站成一排,每个孩子有一个数值。有这样的规则:每个孩子至少得到一颗糖,而数值大于他某个邻居的孩子,所得到的糖必须比该该邻居多。问你总共最少需要发多少糖。

         虽然这是一道HARD难度的题,但我们并不难找出贪心策略的:我们可以将序列看成若干个连续下降子序列的组合。对于每个连续下降组序列,我们将最小的数赋值为1,倒数第二小的数赋值为2,...,以此类推。这样就能得到最小的结果。但这样得出的结果不一定是正确的。有这样特殊的情况需要进一步调整。

         每个连续下降子序列的第一个值必然是大于或等于前一个子序列的最小的值的,但它所赋的值可能并不比前一个序列所赋的值大。一个简单的例子,序列{1,2},我们赋的值为{1,1},这显然是不对的。我们要进一步调整。当第一个值等于前一个序列的最小值的时候,我们可以不用考虑,因为并没有“相等的数值分糖一定要相等”这样的规则;但大于的情况下就要进行调整了。怎么调整呢?很简单,只要将值调整到刚好比前一个的值大1即可。

        代码如下,注意到我们并不需要真正的做到赋值,我们可以直接用1...n的求和公式来得出值的总和,要记录的只是上个序列的最后一个数的赋值罢了。时间复杂度为O(n)。

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size() ;
        if (!n) return 0 ;
        
        int L = 0, R ;
        int lastnum = 0 ;
        int tot = 0 ;
        while (L < n) {
        	R = L + 1 ;
        	while (R < n && ratings[R] < ratings[R-1]) R++ ;
        	tot += (1 + R - L) * (R - L)/2 ;
        	
        	if (L && ratings[L] > ratings[L-1]) tot += max(0, lastnum+1 - (R-L) ) ;
			
			if (R-L == 1 && L && ratings[L] > ratings[L-1]) {
				lastnum = lastnum + 1 ;
			} 
			else lastnum = 1 ;
			
			L = R ;

        }
        return tot ;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值