LeetCode ----135 分发糖果

前言

分发糖果


一、题目

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/candy

二、解法

1.思路

最开始想的时候,就是从ZUO往右,无非就是 小于 大于 相等。
这里相等这个需要注意一下,刚开始我就没注意到为什么评分一样,糖果却可以不一样。
举个例子:
ratings : 【1,2,2,2,3】
result : 【1,2,1,1,2】
上升的时候一直叠加,下降的时候也是依次叠加,类似这样:在这里插入图片描述
黄线即为判定上升和下降序列之间转换的位置.

只要找到每次变化的点,然后初始化值为1,重新叠加即可。
但是这里有个问题需要格外关注一下,类似这样:
在这里插入图片描述

如果下降序列长度大于之前上升的那个序列长度,那么变化点需要前移一位。
刚开始修修补补,写的不是很好:

class Solution():
    def find(self,ratings):
        Sum = 1
        countRise = 1     #记录上升队列的长度
        countDown = 0     #记录下降队列的长度
        if len(ratings) == 1 :
            return 1
        if ratings[0] < ratings[1] :
            pre = 1
        elif  ratings[0] == ratings[1] :
            pre = 2
        else :
            pre = 3
         #用数字 1 2 3 标记 < = >  以此来判断变化点的位置
        for i in range(len(ratings)-1):
            if ratings[i] < ratings[i+1] :
                if pre == 1:
                    countRise += 1
                    Sum += countRise
                else :
                    countRise = 2
                    Sum += countRise
                    pre = 1
            elif ratings[i] == ratings[i+1] :
                countRise = 1
                countDown = 0
                Sum += 1
                pre = 2
            else :
                if pre == 3 :
                    countDown += 1
                    if countDown == countRise :
                        countDown += 1 
                     # 此处判断  下降队列长度是否大于上升队列
                    Sum += countDown
                elif pre == 2 :
                    countDown = 2
                    Sum += countDown
                    #如果前一组是相等的 这组开始下降 那么这组的起点应该是2
                else :
                    countDown = 1 
                    Sum += countDown
                    # 入股前一组是小于 这组开始下降 那么这组的起点应该是1
                pre = 3
        return Sum
      #  Run time: 68ms   Memory consump:16.6MB

在这里插入图片描述
小于的话,起始值是1,可看第一幅图片。
看了其他人答案,发现自己想多了,用上升序列和下降序列两个变量即可,通过下降序列的长度来判断变化点的位置:

class Solution():
    def find(self,ratings):
        Sum = 1
        riseSeq = 1   #起始上升序
        fallSeq = 0   #下降序列

        for i in range(len(ratings)-1):
            if ratings[i] < ratings[i+1] :
                if fallSeq != 0 :
                    riseSeq = 1
                  #判断变化点 对变量值进行初始化
                fallSeq = 0
                riseSeq += 1 
                Sum += riseSeq
            elif  ratings[i] == ratings[i+1] :
                fallSeq = 0
                riseSeq = 1
                Sum += 1
            else:
                fallSeq += 1
                if fallSeq == riseSeq :
                    fallSeq += 1
                  #判断下降序列是否大于上升序列
                Sum += fallSeq
        return Sum	
        #  Run time: 64ms   Memory consump:16.7MB

2.仿写

看了这个作者的答案,真的很强。
作者:mantoufan
链接:https://leetcode-cn.com/problems/candy/solution/dong-tai-gui-hua-qu-jian-dan-shuang-zhi-ca1bl/
想按照他的思路,用python3写出来。

从Zuo往右,然后从右往Zuo:

class Solution():
    def find(self,ratings):
        result = [1] * len(ratings)         #初始化每个孩子都是1 
        for i in range(len(ratings)-1) :    # 从Zuo往右遍历
            if ratings[i+1] > ratings[i] :
                result[i+1] = result[i] + 1
        for j in range((len(ratings)-1),0,-1):     #从右往Zuo遍历 这时候的取大应该考量一下
            if ratings[j-1] > ratings[j] :
                result[j-1] = max(result[j-1],result[j] + 1)
        return sum(result)
        #  Run time: 72ms   Memory consump:16.6MB

用Boolean值判定,就是把之前从Zuo往右一次遍历的方法的判定值改为布尔值:

class Solution():
    def find(self,ratings):
        Sum = 1
        countRise = 1
        countDown = 0
        if len(ratings) == 1 :
            return 1
        if ratings[0] < ratings[1] :
            pre = True                  
        elif  ratings[0] == ratings[1] :
            pre = None
        else :
            pre = False                      #将之前的 1 2  3 改为了 true none false 
        for i in range(len(ratings)-1):
            if ratings[i] < ratings[i+1] :
                if pre :
                    countRise += 1
                    Sum += countRise
                else :
                    countRise = 2
                    Sum += countRise
                    pre = True
            elif ratings[i] == ratings[i+1] :
                countRise = 1
                countDown = 0
                Sum += 1
                pre = None
            else :
                if  not pre :
                    countDown += 1
                    if countDown == countRise :
                        countDown += 1 
                    Sum += countDown
                elif pre  :
                    countDown = 1 
                    Sum += countDown
                else :
                    countDown = 2
                    Sum += countDown
                pre = False
        return Sum
         #  Run time: 64ms   Memory consump:16.6MB   

第一次到了90%多,哈哈!
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值