leetcode 135. Candy

本文介绍了一个有趣的问题——如何分配最少数量的糖果给一排孩子,确保每个孩子至少得到一颗糖果,且评分高的孩子比邻居得到更多。通过建立山峰与山谷的模型,找到所有山谷作为搜索起点,并给出了一种有效的解决方案。

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

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,排名值高的元素要比相邻元素赋值高

这个题目我认为最关键的是建立起模型,其他的就迎刃而解了。把每个元素看做一个山峰的高度,那么这一排山峰中的每个山谷(即比左右都低的)就可以赋值1,然后它的左右就一定要比它高。所以每个山谷就是一次搜索赋值的起点
比如2,1,3,4,5,那么1就是一个山谷,赋值1,然后再往左右一次赋值得到2,1,2,3,4得到结果是12。
所以在代码中首先找到所有山谷,剩下的比较赋值就行了

public int candy(int[] ratings) {
      int len=ratings.length;
         if(len ==0 || len ==1){
             return len;
         }
         int A[] = new int[len];//A[i]=0的是山谷
         if(ratings[0]>ratings[1]){
             A[0]=1;
         }
         if(ratings[len-1]>ratings[len-2]){
             A[len-1]=1;
         }
        for(int i=1;i<len-1;i++){
            if(ratings[i] > ratings[i-1] || ratings[i] > ratings[i+1]){
                A[i]=1;
            }
        }
        int V[] = new int[len];

        for(int i=0;i<len;i++){
            if(A[i] == 0){
                V[i]=1;
                for(int j=i-1;j>=0&&A[j]==1;j--){//从波谷往左遍历
                    if(j-1>=0 && ratings[j-1]<ratings[j] && j+1<len && ratings[j+1]<ratings[j]){
                        V[j]=Math.max(V[j-1], V[j+1])+1;
                    }
                    else if(j-1>=0 && ratings[j-1]<ratings[j]){
                        V[j]=V[j-1]+1;
                    }
                    else if(ratings[j+1]<ratings[j]){
                        V[j]=V[j+1]+1;
                    }
                }
                for(int j=i+1;j<len&&A[j]==1;j++){//从波谷往右遍历
                    if(j-1>=0 && ratings[j-1]<ratings[j] && j+1<len && ratings[j+1]<ratings[j]){
                        V[j]=Math.max(V[j-1], V[j+1])+1;
                    }
                    else if(j-1>=0 && ratings[j-1]<ratings[j]){
                        V[j]=V[j-1]+1;
                    }
                    else if(ratings[j+1]<ratings[j]){
                        V[j]=V[j+1]+1;
                    }
                }
            }
        }

        int sum = 0;
        for(int i=0;i<len;i++){
            sum+=V[i];
        }
        return sum;    
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值