LeetCode135分发糖果

一、题目描述

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

二、解题思路

此题的解决方法分为两步:

1.从左向右对比(当前孩子与左边孩子相对比),当ratings[i]>ratings[i-1]时,i号孩子的糖果会比i-1号学生的多

for(int i=0;iratings[i-1])
    {
        ratings[i]=ratings[i-1]+1;
    }
    else
    {
        left[i]=1;
    }
}

2.从右往左对比(当前孩子与右边孩子对比),当ratings[i]>ratings[i+1]时,i号孩子会比i+1号孩子的糖果多,在此处计算时只用单个变量记录当前位置的右规则

int right=0,ret=0;
for(int i=n-1;i>=0;i--)
{
    if(iratings[i+1])
    {
         right++;
    }
    else{
        right=1;
    }
    ret +=Math.max(left[i],right);
}

三、题目代码

class Solution {
    public int candy(int[] ratings) {
        int n=ratings.length;
        int[] left=new int[n];
        for(i=0;i0&&ratings[i]>ratings[i-1])
            {
                left[i]=left[i-1]+1
            }
            else
            {
                left[i]=1;
            }
            int right =0,ret=0;
            for(int i=n-1;i>=0;i--)
            {
                if(iratings[i+1])
                {
                    right++;
                }
                else{
                    right=1;
                }
                ret +=Math.max(left[i],right);
            }
            return ret;
        }

    }

}

另一种更简洁的解法:

class Solution {
    public int candy(int[] ratings) {
        int n=ratings.length;
        int[] candies=new int[n];
        Arrays.fill(candies,1);

        for(int i=1;iratings[i-1])
            {
            candies[i]=candies[i-1]+1;
            }
        }
        for(int i=n-2;i>=0;i--)
        {
            if(ratings[i]>ratings[i+1])
            {
                candies[i]=Math.max(candies[i],candies[i+1]+1);
            }
        }

        int total=0;
        for(int candy:candies)
        {
            total+=candy;
        }
        return total;
    }

}

四、感悟

题中的left[i]与right[i]分别表示当前孩子与左边/右边的关系,更新的是当前孩子的糖果数。Math.max(left[i],right)表示的是:left[i]表示从左到右遍历,当前孩子i应该分配到的糖果数,right表示从右到左遍历时,当前孩子i应该分配到的糖果数,两者中取较大值,作为当前孩子i的最终糖果数。

你可能感兴趣的:(java,贪心算法,leetcode)