力扣面试经典第135题“分发糖果”的分析及解决

135. 分发糖果

困难

问题描述:

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

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

每个孩子至少分配到 1 个糖果。

相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

输入:ratings = [1,0,2]

输出:5

解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

示例 2:

输入:ratings = [1,2,2]

输出:4

解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。

第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

处理思路:

1、单独设置一个与每位小朋友评分对应的获得糖果数目的列表,并设初始值为1。

2、按评分从低到高依次处理小朋友获得的糖果数目。先处理评分低的,因为处理过后其获得的糖数就不会变了,再依次处理评分高的。

3、经过一轮处理,最后就可以取得每位小朋友获得的糖数,并以列表形式呈现。

4、对列表中数据求和即可求出最少要准备的糖果数目。

程序如下:

#输入评分列表数据

ratings=eval(input('pls input ratings='))

n=len(ratings)



#列表a中数据是每一个小朋友获得的糖数,因为至少都有1个,所以初始值都为1

a=[1]*n



#函数gf(i,ratings)是通过索引号i对小朋友评分以及获得的糖果数目进行处理

def gf(i,ratings):

    if i==0:

        if  ratings[i]>ratings[i+1] and a[i]<=a[i+1]:

            a[i]=a[i+1]+1

    elif i==len(ratings)-1:

        if ratings[i]>ratings[i-1] and a[i]<=a[i-1]:

            a[i]=a[i-1]+1

    else:

        if ratings[i]>ratings[i+1] and ratings[i]>ratings[i-1]:

            a[i]=max(a[i+1],a[i-1])+1

        elif ratings[i]>ratings[i+1] and ratings[i]<=ratings[i-1] and a[i]<=a[i+1]:

            a[i]=a[i+1]+1

        elif ratings[i]>ratings[i-1] and ratings[i]<=ratings[i+1] and a[i]<=a[i-1]:

            a[i]=a[i-1]+1



#去掉ratings中的重复项,并按从低到高排序存于b列表中

b=sorted(list(set(ratings)))



#按评分从低到高的顺序,依次取得相应评分的索引号存入c中

c=[]

for i in b:

    m=ratings.count(i)

    s=0

    for j in range(m):

        k=ratings.index(i,s)

        c.append(k)

        s=k+1



#按c中索引号的顺序,依次对ratings和获得糖数的列表a进行处理

#最后的a列表中就是每位小朋友获得的糖果数量

for i in c:

    gf(i,ratings)    

print('每位小朋友获得的糖数:',a)



#对a列表每位小朋友糖的数量求和即为需要准备的最少糖果数目

print('需要准备的最少糖果数目:',sum(a))

运行实例1

pls input ratings=[1,0,3,2,5]

每位小朋友获得的糖数: [2, 1, 2, 1, 2]

需要准备的最少糖果数目: 8

运行实例2

pls input ratings=[1,9,1,2,3,5]

每位小朋友获得的糖数: [1, 2, 1, 2, 3, 4]

需要准备的最少糖果数目: 13

总结:

  1. 良好的数据处理习惯有助于解决问题。
  2. 通过运行实例可以看出,糖果分配不公平,评分高的不一定就一定能够分得更多的糖果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值