zoukankan      html  css  js  c++  java
  • leetcode Candy

    1 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?

    解析:

    1 先求出相邻小孩的优先级。

    2 积分得到每个小孩的糖果数。再加上最小小孩糖果数等于1的限制条件。

    3 积分得到总的糖果数。

    代码如下:

     1     /*
     2      * 优先级相同时,糖果数相同
     3      */
     4     private int sign(int i) {
     5         if (i > 0) { return 1; }
     6         if (i < 0) { return -1; }
     7         return 0;
     8     }
     9     
    10     private int[] candyDelta(int[] ratings) {
    11         // delta保存与上一个小孩的优先级
    12         int[] delta = new int[ratings.length];
    13         delta[0] = 0;
    14         for (int i = 1; i < ratings.length; i++) {
    15             delta[i] = sign(ratings[i] - ratings[i-1]);
    16         }
    17         return delta;
    18     }
    19     
    20     private int calCandies(int[] delta) {
    21         // 计算第一个小孩糖果数为0时,每一个小孩的糖果数。这里糖果数可能为负。
    22         int[] candies = new int[delta.length];
    23         candies[0] = 0;
    24         for (int i = 1; i < candies.length; i++) {
    25             candies[i] = candies[i-1] + delta[i];
    26         }
    27 
    28         // 找到糖果数最小的小孩
    29         int min = Integer.MAX_VALUE;
    30         for (int i = 0; i < candies.length; i++) {
    31             if (min > candies[i]) {
    32                 min = candies[i];
    33             }
    34         }
    35         
    36         // 糖果数最小的小孩给1个糖果,并据此分配糖果给其他小絯
    37         for (int i = 0; i < candies.length; i++) {
    38             candies[i] = candies[i] - min + 1; 
    39         }
    40         // 计算糖果数
    41         Integer total = 0;
    42         for (int candy : candies) {
    43             total += candy;
    44         }
    45         return total;
    46     }
    47     
    48     public int candy(int[] ratings) {   
    49         if (ratings.length == 1) {
    50             return 1;
    51         }
    52         
    53         int[] delta = candyDelta(ratings);
    54 
    55         int total = calCandies(delta);
    56 
    57         return total;
    58     }
    View Code

    2 Candy

    代码1放到leetcode中,通不过{1,2,2}这个测试用例,返回5,而leetcode结果是4。其原因在于题设中并没有限定两个相邻的rating相同的小孩的糖果数相等。

    可以在有相邻小孩rating相同处截断,然后分别计算两部分的candies。

    更进一步的,可以从左往右计算,在左边小孩权重不小于右边小孩处截断;然后从右往左计算,在右边小孩权重不小于左边小孩处截断。

    即从左往右报数时,第一次的计算结果是满足条件的;从右往左报数时,第二次的计算结果是满足条件的。最后将两次的计算结果合并,即为最终解。

    代码如下:

     1     private void calCandies(int[] candies, int[] ratings) {
     2         candies[0] = 1;
     3         if (ratings.length == 1) { return; }
     4         
     5         // 从左往右
     6         int[] candiesLeft = new int[ratings.length];
     7         candiesLeft[0] = 1;
     8         for (int i = 1; i < ratings.length; i++) {
     9             if (ratings[i] > ratings[i-1]) {
    10                 candiesLeft[i] = candiesLeft[i-1] + 1;
    11             }else {
    12                 candiesLeft[i] = 1;
    13             }
    14         }
    15         
    16         // 从右往左
    17         int[] candiesRight = new int[ratings.length];
    18         candiesRight[ratings.length-1] = 1;
    19         for (int i = ratings.length-2; i >= 0; i--) {
    20             if (ratings[i] > ratings[i+1]) {
    21                 candiesRight[i] = candiesRight[i+1] + 1;
    22             }else {
    23                 candiesRight[i] = 1;
    24             }
    25         }
    26         
    27         // 合并
    28         for (int i = 0; i < candies.length; i++) {
    29             candies[i] = Math.max(candiesLeft[i], candiesRight[i]);
    30         }
    31     }
    32 
    33 
    34     public int candy(int[] ratings) {
    35         if (ratings.length == 1) {
    36             return 1;
    37         }
    38 
    39         int[] candies = new int[ratings.length];
    40         calCandies(candies, ratings);
    41 
    42         // 计算糖果数
    43         Integer total = 0;
    44         for (int candy : candies) {
    45             total += candy;
    46 
    47         }
    48         return total;
    49     }
    View Code
  • 相关阅读:
    Netty入门(三)之web服务器
    Math对象
    DOM
    BOM
    字符串
    数组
    ajax
    如何安装vue脚手架
    git提交拉取远程仓库
    第九届蓝桥杯,赛后感!!含泪写完。
  • 原文地址:https://www.cnblogs.com/yanyichao/p/3941736.html
Copyright © 2011-2022 走看看