135. Candy
难得一见的有具体场景的题
题干:
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
Each child must have at least one candy.
Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
解释:
这个题理解起来其实也很简单,就是有一排小孩,需要发糖,满足两个要求: 1,所有小孩都要有糖 2,比邻居分数高的小孩的糖必须更多
思考:
这个题的两个条件其实可以翻译一下,第一个条件是,局部分数最低的小孩的糖数为1,局部分数最低其实就是小于两个邻居的小孩,一次遍历即可找到所有的这样最低点。第二个条件,分数比邻居高的小孩的糖数必须是左右邻居中最大值加一的数额。因此我们只要初始化一个一维的dp数组,遍历每个起点,找到满足以上条件的最小值,然后把每个位置的最小值都加起来即可得到全局最小值。击败27.41% 感觉只要不是用的经典算法,而是按照业务逻辑去写,一般复杂度都会比经典算法高
答案:
class Solution(object):
def candy(self, ratings):
"""
:type ratings: List[int]
:rtype: int
"""
#遍历数组找到所有的source点
if len(ratings)==1:
return 1
dp=[1]*len(ratings)
sources=[]
for i in range(0,len(ratings)):
if i ==0:
if ratings[0]<=ratings[1]:
sources.append(0)
continue
elif i ==len(ratings)-1:
if ratings[i]<=ratings[i-1]:
sources.append(i)
continue
elif ratings[i]<=ratings[i-1] and ratings[i]<=ratings[i+1]:
sources.append(i)
for source in sources:
self.helperLeft(dp,source,ratings)
self.helperRight(dp,source,ratings)
return sum(dp)
def helperLeft(self,dp,source,ratings):
if source-1<0:
return
if ratings[source-1]<=ratings[source]:
return
dp[source-1]=max(dp[source]+1,dp[source-1])
self.helperLeft(dp,source-1,ratings)
return
def helperRight(self,dp,source,ratings):
if source+1>=len(ratings):
return
if ratings[source+1]<=ratings[source]:
return
dp[source+1]=max(dp[source]+1,dp[source+1])
self.helperRight(dp,source+1,ratings)
return
答案补充:
也可以用两次遍历的写法,第一次从前往后,第二次从后往前。我这个写法实际上是遍历了每个点两遍才找到所有的谷点。