【leetcode】Candy(python)

题目要求比其高的邻居要比本身的奖励多,那么最少也要多一个,所有我们可以找到所有的凹点,凹点如下三种情形。

找到所有的凹点后,我们就可以从凹点处开始向左右两个方向依次查找递增序列,其中每个高的都要比相邻的矮的多一个,比如1,2,5,4.我们找到凹点为1 和4,那么从1开始向左没有其他点,我们向右,依次得到2 比1高,2的糖果应该是1的基础上加1,为2, 5比2高,5的糖果是在2的基础上加1,为3。令一个凹点4, 向左,5比4高,5的糖果应该是在4的基础上加 1,为2,这时我们发现冲突了,从凹点1 开始,我们得到的5的糖果是3,但是从凹点 4 开始,我们得到的糖果数却为2 ,此时我们选择哪个呢?当然,如果要少的,当然是2,但是它却违反了题目中的限定条件,5如果为2
,就不比2的糖果数多了,所以这时我们就应该选择最大的,这说明了什么呢?说明从左面开始向右到 5 得到的递增序列的长度大于从4开始向左到5得到的递增序列。也就是说,得到的糖果数的多少,取决于所构成的连续递增序列的长度。

class Solution:
	def candy(self, A):
		if len(A) == 0: return 0
		candies = [1] * len(A)
		#insert two guard at both bounder
		#为了便于处理凹点,我们在左右边界各插入一个点作为哨兵,这样在比较的时候
		#就不用额外处理边界点了。
		A.insert(0, A[0])
		A.append(A[-1])
		#pits 用来存储所有的凹点下标
		pits = []
		for i in range(1, len(A) - 1):
			if A[i] <= A[i - 1] and A[i] < A[i + 1] or 				A[i] <= A[i + 1] and A[i] < A[i - 1]:
				pits.append(i)
	    #从左到右一次处理各个凹点
		for i in pits:
			# go left
			j = i
			while A[j - 1] > A[j]:
			    #因为A数组加入了哨兵的缘故,所以A和candies的下标不是严格对齐的,差了一个
				if candies[j - 2] < candies[j - 1] + 1:
					candies[j - 2] = candies[j - 1] + 1
					j -= 1
				else: break
			# go right
			j = i
			while A[j + 1] > A[j]:
				if candies[j] < candies[j - 1] + 1:
					candies[j] = candies[j - 1] + 1
					j += 1
				else: break
		return sum(candies)

这里我们需要一个额外的pits数组来存储所有的凹点,其实通过刚才我们的分析,另外一种实现方式已经出现了,就是从左开始,找递增序列,然后增加糖果,对于每个数,它和左边构成的递增序列与从右面构成的递增序列可能不一样,如上例中的5,跟左边够成的递增序列为 1,2 5,长度为3,跟右面的构成的递增序列为4,5,长度为2,而5最少的糖果数是取决于最长的递增序列的。所以我们就可以从左到右遍历一遍,然后再从右向左遍历一遍,取两次遍历的最大值。

class Solution:
	def candy(self, A):
		if len(A) == 0: return 0
		candies = [1] * len(A)
		#从左向右,按着递增来分配糖果
		for i in range(1, len(A)):
		    if A[i] > A[i - 1]:
		        candies[i] = candies[i - 1] + 1

		#从右向左,按着递增来分配糖果,并取最大值
		for i in xrange(len(A) - 2, -1, -1):
		    if A[i] > A[i + 1] and candies[i] < candies[i + 1] + 1:
		        candies[i] = candies[i + 1] + 1

		return sum(candies)  

【leetcode】Candy(python),布布扣,bubuko.com

时间: 2024-10-25 03:13:55

【leetcode】Candy(python)的相关文章

【LeetCode】动态规划(下篇)

[600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offers [639] Decode Ways II [646] Maximum Length of Pair Chain [647] Palindromic Substrings [650] 2 Keys Keyboard [651] 4 Keys Keyboard [656] Coin Path [6

【leetcode】Candy(hard) 自己做出来了 但别人的更好

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

【2014】字符串(3)

题目描述(50分): 通过键盘输入100以内正整数的加.减运算式,请编写一个程序输出运算结果字符串. 输入字符串的格式为:"操作数1 运算符 操作数2","操作数"与"运算符"之间以一个空格隔开. 补充说明: 1.操作数为正整数,不需要考虑计算结果溢出的情况. 2.若输入算式格式错误,输出结果为"0". 要求实现函数: void arithmetic(const char *pInputStr, long lInputLen,

【Spring】的【Bean】管理(注解)【四个相同功能的注解】

[Spring]的[Bean]管理(注解)[四个相同功能的注解] 注解:代码里面特殊的标记,使用注解也可以完成一些相关的功能. 注解写法:@注解名称(属性名称=属性值) 注解使用在类.方法.属性上面 (注解可以替代配置文件,并非完全替代): 1.创建类,创建方法 1 public class User { 2 public void add(){ 3 System.out.println("add-----------"); 4 } 5 } 2.创建spring配置文件,引入约束 1

【leetcode】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

【2014】 字符串(2)

题目描述(40分): 通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串. 压缩规则: 1.仅压缩连续重复出现的字符.比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc". 2.压缩字段的格式为"字符重复的次数+字符".例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz". 要求实现函数: v

【2014】字符串(1)

一.题目描述(60分): 通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉. 比如字符串"abacacde"过滤结果为"abcde". 要求实现函数:void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr); [输入] pInputStr:  输入字符串 lInputLen:  输入字符串长度 [

【分享】Linux(Ubuntu)下如何自己编译JDK

最近在看<深入理解 Java 虚拟机>这本书.里面提到了如何手动编译JDK,于是就试了试. 在编译的过程中,遇到了一些问题.上网一搜,发现了一篇很好的文章,跟大家分享一下:ubuntu 13.04环境编译OpenJDK7 虽然文章里说的编译环境是 13.04 ,但笔者在 14.04 的环境下,参考着文章也能成功编译. [分享]Linux(Ubuntu)下如何自己编译JDK

【2012】数组(2)

给定一个数组input[] ,如果数组长度n为奇数,则将数组中最大的元素放到 output[] 数组最中间的位置,如果数组长度n为偶数,则将数组中最大的元素放到 output[] 数组中间两个位置偏右的那个位置上,然后再按从大到小的顺序,依次在第一个位置的两边,按照一左一右的顺序,依次存放剩下的数.      例如:input[] = {3, 6, 1, 9, 7}   output[] = {3, 7, 9, 6, 1};             input[] = {3, 6, 1, 9,