leetCode Candy解题分享

原题:https://oj.leetcode.com/problems/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)正确理解题意!

注意题目中的表达:有更高rating的child要比他们的 “邻居” 有更多的糖果。有两点很容易误解需要注意:

a)如果两个孩子是邻居,那么有更高rating的孩子必须有更多的糖果,如果两个孩子不是相邻,他们糖果数目相对多少跟自己的rating没有必然联系!

b)对于相邻的孩子,其ratings相等的情况并没有要求,如果两个相邻的孩子rating相等,他们的糖果数目可以不相等。

2)在正确理解了题意的基础上,给每个孩子计算出他应该得多少块糖。方法如下:

对于任意一个孩子,他的糖果数需要考虑两点:

a)他的rating跟前面孩子rating的关系---如果rating比前面的孩子高,那么他得到的糖数至少为前面孩子糖果数+1(后续代码中的candyArr[i-1] + 1),如果其rating小于等于(注意包括等于)前面孩子的rating,则无需考虑前面孩子糖果数的关系。

b)他的rating跟后面孩子rating的关系(注意不能只考虑他的邻居)----这个是难点,解决方法是:查看他后面rating值严格单调递减的孩子数目。

举例:ratings: 5,4,3,2,2,x........

对于rating=5这个孩子来说,他后面严格单调递减的孩子有三个,分别是:4,3,2。接下去的连续的2已经不需要考虑,理由如a)中所述,也就是后面的2这个孩子的糖果数已经跟前面无关系,不受前面限制了。这样,我们需要给rating=5这个孩子留出3的可减空间,以便他后面孩子糖果数至少为1。  也就是说,考虑这个孩子跟后面孩子ratings的关系,他至少应该有1+3=4块糖。

       最后,同时满足a)和b)条件的数字,就是当前这个孩子应该分发的糖果数。


AC代码:

public class Candy {
	
	public int candy(int[] ratings) {
		
		if(ratings == null || ratings.length == 0) return 0;
		
		int length = ratings.length;
		
		int[] minSpaceForFollows = new int[length]; //用一个数组来记录每个孩子需要给他后面孩子留出的可减空间
		
		for(int i=0;i<length;i++) {
			int space = 0;
			for(int j=i+1;j<length;j++) {
				
				if(ratings[j] >= ratings[j-1]) {
					break;
				} else {
					space++;
				}
				
			}
			minSpaceForFollows[i] = space;
			
		}
		
		int result = 0;
		int[] candyArr = new int[length];
		candyArr[0] = (minSpaceForFollows[0] + 1);
		result += candyArr[0];
		
		for(int i=1;i<minSpaceForFollows.length;i++) {
			int leftFactor = 1;
			if(ratings[i] > ratings[i-1]) {   //这个孩子糖果数考虑他前面孩子所需的最小值
				leftFactor = candyArr[i-1] + 1;
			}
			int rightFactor = 1 + minSpaceForFollows[i];   //这个孩子考虑他后面孩子所需的最小值
			candyArr[i] = Math.max(leftFactor, rightFactor);
			result += candyArr[i];
		}
		
		return result;
		
		
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值