[Leetcode 135, Hard] Candy

本文介绍了一种解决糖果分配问题的算法,目标是最小化分配给儿童的糖果总数,同时确保评分较高的儿童比邻居获得更多的糖果。该算法使用了回溯法,并详细展示了C++实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem:

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?

Algorithm:

方法一:回溯法。

根据条件,每个孩子至少得到一块糖。所以,如果要得到最优解知道给每个评价最低的孩子(ratings的极小元)一块糖。然后,从这个极小点向回(后)分配糖。在这道题里,只有rating高(至少1)才能得到更多的糖。所以,如果两个人的rating相同,那么第二个人就只需要给一块糖就可以了。如此把所有孩子的糖分配完毕就可以了。

2. There is no comparements if the peak is at 0 or len-1.

Solutions:

C++:

int candy(vector<int> &ratings) {
        int len=ratings.size();
        if(len==0) return 0;
        if(len==1) return 1;
        
        vector<int> candy(len, 0);
        int peak=0, bottom=0;
        bool touchEnd=false;
        for(int start=0; start<len-1;){
            //Iterate from the zero pos to the last one.
            if(ratings[start]<=ratings[start+1]){
                //Asending sunseq.
                candy[start]=1;
                for(int j=start+1; j<len; ++j){
                    if(ratings[j]>ratings[j-1]){
                        candy[j]=candy[j-1]+1;
                    }else if(ratings[j]==ratings[j-1]){
                        candy[j]=1;   
                    }else{
                        peak=j-1;
                        break;
                    }
                    if(j==len-1) touchEnd=true;
                }
            }
            if(touchEnd) break;
            
            //Find the next local min rating.
            for(int k=peak+1; k<len; ++k){
                if(ratings[k]>ratings[k-1]){
                    bottom=k-1;
                    break;
                }
                if(k==len-1) bottom=k;
            }
            
            //Assign the amount of candies in a backtracking way.
            candy[bottom]=1;
            for(int k=bottom-1; k>peak; --k){
                if(ratings[k]==ratings[k+1]) candy[k]=1;
                else candy[k]=candy[k+1]+1;
            }
            
            //Reassign the amount of candies of the k-th child.
            if(peak==0){
                candy[peak]=candy[peak+1]+1;
            }else if(peak==len){
                candy[peak]=candy[peak-1]+1;
            }else{
                if(ratings[peak]>ratings[peak+1] && candy[peak]<=candy[peak+1]) candy[peak]=candy[peak+1]+1; 
                if(ratings[peak]>ratings[peak-1] && candy[peak]<=candy[peak-1]) candy[peak]=candy[peak-1]+1; 
            }
            start=bottom;
        }
        
        int sum=0;
        for(int i=0; i<len; ++i) sum+=candy[i];
        return sum;
        
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值