LeetCode 135. 分发糖果

LeetCode 135. 分发糖果

解题思路和代码

我们可以举一个比样例稍微好一点的例子[7,8,4,2,1,3,5,9,7]

首先可以想到第一种思路:

  • 我们先定义一个数组candies,这个数组存放着每个人最终获得的糖果。
  • 接着我们找到数组的最小值及其下标定义为sym。如果是第一次遍历,则直接令candies[sym]=1,因为每一位小朋友至少要有一个糖果。在例子中这个最小值是1,sym=4
  • 然后我们利用快速排序的思想,最小值的两边分别递归再次寻找最小值。即[7,8,4,2][3,5,9,7]再次寻找最小值,以此类推。获得最小值之后,和左右两边比较一下,如果左边或者右边的的candies数组值不为0,则自身的candies数组值为candies[sym]=max(candies[sym],candies[sym-1]+1,candies[sym+1])。当然这里我们假设sym-1sym+1的值都是合法的。

但是这种方法的时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn),最后三个数据过不了,超时了。那么有没有 O ( n ) O(n) O(n)的方法呢,答案是有的


class Solution:

    def dfs(self, ratings, apples, st, ed):

        if st > ed:
            return

        mmin = 0x7fffffff
        sym = 0
        for index in range(st, ed+1):
            if ratings[index] < mmin:
                mmin = ratings[index]
                sym = index

        if apples[sym] == 0:
            apples[sym] += 1

        if (sym-1) >= 0:
            # if mmin == ratings[sym-1]:
            #     apples[sym] = max(apples[sym], apples[sym-1])
            if mmin > ratings[sym-1]:
                apples[sym] = max(apples[sym], apples[sym-1]+1)

        if (sym+1) < len(ratings):
            # if mmin == ratings[sym+1] and apples[sym+1] != 0:
            #     apples[sym] = max(apples[sym], apples[sym+1])
            if mmin > ratings[sym+1]:
                apples[sym] = max(apples[sym], apples[sym+1]+1)

        if (sym-1) >= 0:
            self.dfs(ratings, apples, st, sym-1)
        if (sym+1) < len(ratings):
            self.dfs(ratings, apples, sym+1, ed)

 

    def candy(self, ratings):
        """
        :type ratings: List[int]
        :rtype: int
        """
        apples = []

        for index in range(len(ratings)):
            apples.append(0)

        self.dfs(ratings, apples, 0, len(ratings)-1)

        ans = 0
        for index, number in enumerate(apples):
            ans += number
        
        return ans

第二种思路:
我观察了一下数组,发现8这个点为什么它的糖果为4,那是因为后面有四个数比他小啊,那是不是可以利用逆序数的思想呢?

  • 首先我们先定义两个数组left和right,left就是从左到右,按照正序的顺序。对于我们的例子来说,最终得到的left数组为[1,2,1,1,1,2,3,4,1]。right就是从右到左,按照逆序的顺序,最终的到的数组为[1,4,3,2,1,1,1,2,1]
  • 最后我们遍历同时遍历一遍right数组和left数组,第i个位置的candies[i]=max(left[i],right[i])

这个算法的时间复杂度就是 O ( n ) O(n) O(n),该算法虽然能过但是时间花的好像还是挺久的,各位大佬们如果有更好的算法欢迎交流,不喜勿喷。


class Solution:

    def deal(self,ratings):

        left = [0 for i in range(len(ratings))]
        right = [0 for i in range(len(ratings))]

        for index, number in enumerate(ratings):
            if index == 0:
                left[index] = 1
            else:
                if number > ratings[index-1]:
                    left[index] = left[index-1]+1
                else:
                    left[index] = 1

        for index in range(len(ratings)-1, -1, -1):
            if index == len(ratings)-1:
                right[index] = 1
            else:
                if ratings[index] > ratings[index+1]:
                    right[index] = right[index+1]+1
                else:
                    right[index] = 1

        ans = 0
        for index in range(len(left)):
            ans += max(left[index], right[index])

        return ans


    def candy(self, ratings):
        """
        :type ratings: List[int]
        :rtype: int
        """
        return self.deal(ratings)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值