LeetCode: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?

有N个孩子站成一排,每个孩子有一个分值。给这些孩子派发糖果,需要满足如下需求:

  • 1、每个孩子至少分到一个糖果
  • 2、分值更高的孩子比他相邻的孩子获得更多的糖果

求至少需要分发多少糖果?

要求示例:

输入描述:0,1,0
输出描述:4

输入示例:5,4,1,1
输出示例:7

题目分析:

  • 每个孩子至少一个;
  • 分值高的比相邻的孩子糖果多;

假如输入:1,2,2,那第一个孩子1个,第二个孩子2个,第三个孩子呢?按题意,分1个就行。也就是至少四个。

思路一:

  • 初始将每个孩子的糖果数都设为1;
  • 从左向右扫描,保证一个方向上分数更大的糖果更多;
  • 从右向左扫描,保证另一个方向上分数更大的糖果更多。
import java.util.Arrays;
public class Solution {
    public int candy(int[] ratings) {
        if(ratings == null || ratings.length == 0) {
            return 0;
        }
        
        //初始将每个孩子的糖果数都设为1
        int[] count = new int[ratings.length];
        Arrays.fill(count, 1);

        int sum = 0;
        //从左向右扫描,保证一个方向上分数更大的糖果更多
        for (int i = 1; i < ratings.length; i++) {
            if (ratings[i] > ratings[i - 1]) {
                count[i] = count[i-1] + 1;
            }
        }
        //从右向左扫描,保证另一个方向上分数更大的糖果更多
        for (int i = ratings.length - 1; i > 0; i--) {
            sum += count[i];
            //左侧分值高于右侧,左侧糖果数不多于右侧
            if (ratings[i] < ratings[i - 1] && count[i] >= count[i-1]) {
                //左侧糖果数等于右侧糖果数+1
                count[i-1] = count[i]+1;
            }
        }

        sum += count[0];
        return sum;
    }
}

思路二:

  • 从头开始,第一个小朋友给一个糖果,若是升序,则后面小朋友的糖果数依次+1,一直遇到降序。
  • 遇到降序怎么处理?因为我们需要给尽可能少的糖果,但需要保证降序的最后一个至少有一个糖果。
  • 此时采用贪心策略:先得到降序的位数,用等差求和,公差为1,算出递减阶段需要给的糖果数,递减的最后一个人肯定是给1个。
  • 此时还需要注意:递减开始的小朋友的糖果不能比它的前一个小朋友多,如果多了,那需要额外补给他的前一个小朋友糖果,来满足题目第二个条件。

例子: 假如输入序列是 [1,3,5,7,6,5,4,3,2,1], 前四个小朋友糖果数分别为1,2,3,4。从第五个小朋友开始变成递减序列。那个第五个小朋友至少分到:6个。可是第四个小朋友7大于第五个小朋友6,但7只有4个糖果而6有6个,显然不合理,为满足题目第二个条件,所以必须给7小朋友补发糖,要补多少个糖果呢?两个小朋友相差6-4=2个,但是补2个无法满足要求,所以要补2+1=3个,也就是小朋友7拿到7个,小朋友6拿6个,这才符合题目要求。

public class Solution {
    public int candy(int[] ratings) {
        if (ratings == null || ratings.length == 0) {
            return 0;
        }

        int pre = 1, countDown = 0, total = 1;
        for (int i = 1; i < ratings.length; i++) {
            if (ratings[i] >= ratings[i - 1]) {
                if (countDown > 0) {
                    total += countDown * (countDown + 1) / 2;

                    if (countDown >= pre) {
                        total += countDown - pre + 1;
                    }

                    pre = 1;
                    countDown = 0;
                }

                pre = ratings[i] == ratings[i - 1] ? 1 : pre + 1;
                total += pre;
            } else {
                //逆序位数
                countDown++;
            }
        }

        if (countDown > 0) {
            total += countDown * (countDown + 1) / 2;
            if (countDown >= pre) {
                total += countDown - pre + 1;
            }
        }
        return total;
    }
}
发布了95 篇原创文章 · 获赞 16 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tiankong_12345/article/details/90113904
今日推荐