【LeetCode-135】Candy

本文探讨了一道关于糖果分配的问题,通过两种不同的算法实现了解决方案。一种是先正向扫描再反向扫描的方法,另一种是针对递减序列进行特殊处理的策略。两种方法都确保了每个评分更高的孩子得到更多糖果。

这道题真是让我有点陶醉,开始自己的思路空间复杂度最低,时间复杂度O(n),调了2小时也没ac!就看了别人的思路,别人思路最终自己实现了,但是我还是不服气,不信做不出来,最后废了九牛二虎之力终于ac了!!!

public class ImportantCandy {
	//别人的思路
	public int candy(int[] ratings) {
		if(ratings == null || ratings.length == 0){
			return 0;
		}
		int res = 0;
        int[] candys = new int[ratings.length];
        Arrays.fill(candys,1);
        
        //正向扫描一遍
        for(int i = 1;i < ratings.length;i ++){
        	if(ratings[i] > ratings[i - 1]){
        		candys[i] = candys[i - 1] + 1;
        	}
        }
        //反向扫描一遍
        for(int i = ratings.length - 2;i >= 0;i --){
        	//第二个条件很重要,因为如果左边糖果数本身就已经比右边多了(candys[i] > candys[i + 1]),
        	//那么改成 cans[i] = cans[i + 1] + 1; 就有可能把 cans[i] 变小
        	if(ratings[i] > ratings[i + 1] && candys[i] <= candys[i + 1]){
        		candys[i] = candys[i + 1] + 1;
        	}
        }
        
        for(int i = 0;i < candys.length;i ++){
        	res = res + candys[i];
        }
        return res;
    }
	
	//我的思路
	public int candy1(int[] ratings){
		if(ratings == null || ratings.length == 0){
			return 0;
		}
        int res = 1;
        
        //连续下降序列的开始下标
        int decBegin = 0;
        //连续下降序列的结束下标
        int decEnd = 0;
        //当前孩子拿到的糖数
        int currentCandy = 1;
        //未进入递减序列时的那个孩子分得的糖数
        int preContinuousDecCount = 1;
        
        for(int i = 1;i < ratings.length;i ++){
        	if(ratings[i] < ratings[i - 1]){
        		decEnd ++;
        		//判断连续下降序列的长度是否大于未进入递减序列时的那个孩子分得的糖数
        		int continusDecCount = decEnd - decBegin + 1;
        		//下面这两步很关键额
        		//长度  > preContinuousDecCount,则那个孩子糖数需要修改
        		if(continusDecCount > preContinuousDecCount){
        			res += decEnd - decBegin + 1;
        		}
        		//长度 < preContinuousDecCount,则那个孩子的糖数不需要修改
        		else{
        			res += decEnd - decBegin;
        		}
        		
        		//保证一旦离开递减序列,则candy必须从1计数
        		currentCandy = 1;
        	}
        	
        	else{
        		//如果当前等级大于前一个的等级,则当前人分的糖数比前一个人多1个
        		if(ratings[i] > ratings[i - 1]){
        			currentCandy ++;
        		}
        		//如果当前等级等于前一个的等级,则当前人分的糖为1个
        		else{
            		currentCandy = 1;
        		}
        		//一旦不是递减序列,则将递减的开始和结束下标和当前下标一致
        		decBegin = i;
        		decEnd = decBegin;
        		
        		//未进入递减序列,则将当前的糖数赋值给preContinuousDecCount
        		preContinuousDecCount = currentCandy;
        		
        		res += currentCandy;
        	}
        }
        
        return res;
	}
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值