LeetCode 135. Candy

来源:互联网 发布:仿微信图文编辑器源码 编辑:程序博客网 时间:2024/05/18 01:18

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

         虽然这是一道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
原创粉丝点击