• lc面试准备:Candy


    1 题目

    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?

    接口

    int candy(int[] ratings)
    几个小孩站一排,每个小孩有个等级值,现在给小孩发糖,发的时候要遵守2个规则:(1)每个小孩至少一颗糖(2)两个相邻的小孩中,等级大的小孩一定比等级小的小孩糖多,求发糖的数目的最小值。

    2 思路

    基本思路:先进行2次扫描,一次从左往右,一次从右往左。最后一次扫描累加出结果。
    第一次扫描:维护对于每一个小孩左边所需要最少的糖果数量,存入数组对应元素中。
    第二次扫描:维护右边所需的最少糖果数。
    第三次扫描:将左边和右边大的糖果数量累加到result,从而累加得出结果。
    example: ratings = [3,4,5,1,2,3]
     
    ratings 3 4 5 1 2 3
    lefts 1 2 3 1 2 3
    rights 1 1 2 1 1 1
    两者最大值 1 2 3 1 2 3
    result = sum(1,2,3,1,2,3) = 12

    复杂度

    方法只需要3次扫描,所以时间复杂度是O(3*n)=O(n)。空间上需要2个长度为n的数组,复杂度是O(n)。

    3 代码

     1     public int candy(int[] ratings) {
     2         final int len = ratings.length;
     3         int[] lefts = new int[len];
     4         int[] rights = new int[len];
     5 
     6         // scan from left to right
     7         lefts[0] = 1;
     8         for (int i = 1; i < len; i++) {
     9             if (ratings[i] > ratings[i - 1]) {
    10                 lefts[i] = lefts[i - 1] + 1;
    11             } else {
    12                 lefts[i] = 1;
    13             }
    14         }
    15 
    16         // scan from right to left
    17         rights[len - 1] = 1;
    18         for (int i = len - 2; i >= 0; i--) {
    19             if (ratings[i] > ratings[i + 1]) {
    20                 rights[i] = rights[i + 1] + 1;
    21             } else {
    22                 rights[i] = 1;
    23             }
    24         }
    25 
    26         // calculate min nums of candy 
    27         int result = 0;
    28         for (int i = 0; i < len; i++) {
    29             result += Math.max(lefts[i], rights[i]);
    30         }
    31         return result;
    32     }

    4 总结

    • 小朋友分糖,影响因素都是由左右两边的最值来决定的。
    • 这种两边扫描的方法是一种比较常用的技巧,LeetCode中Trapping Rain Water和这道题都用到了,可以把这种方法作为自己思路的一部分,通常是要求的变量跟左右元素有关系的题目会用到。 From Code Ganker
    • code可以将第三次扫描省掉,把第三次扫描的工作放到第二次里面做,现在不推荐做,因为显得结题思路不清晰。

    5 扩展

    Trapping Rain Water

    6 参考

  • 相关阅读:
    gdb段错误
    gdb断点
    init.d详解
    asp.net中的服务器端控件 textbox 设为只读属性后无法获取 javascript给其赋的值
    关于“金点子”征集通知
    Notepad++ SQL Assistant
    IoC Container Benchmark Unity, Windsor, StructureMap and Spring.NET
    如何判断个人电脑是多少位(32位?还是64位系统)
    批量执行SQL文件
    SQL Server 2005 dev 开发板 版本说明
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/4315858.html
Copyright © 2020-2023  润新知