zoukankan      html  css  js  c++  java
  • LeetCode:Candy

    题目地址:here

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

    本文提供两个算法,第一个是我自己做题时用的,第二个是网上看题解时看到的

    算法1:该算法采用分治发,把小孩平均分左右两拨,求得两拨小孩的最小值分配方案后,还得看分界线出是否满足规则。我们用L[end]表示左边一拨小孩的右边界,R[start]表示右边一拨小孩的左边界,处理分界线出的情况分以下两种:

    (1)如果L[end]等级比R[start]高,但是糖数少或相等,那么就从左边一拨小孩的右边界依次调整糖数以满足规则;

    (2)如果L[end]等级比R[start]低,但是糖数多或相等,那么就从右边一拨小孩的左边界依次调整糖数以满足规则;

    该算法时间复杂度为O(N*lgN)

    算法1代码如下:

     1 class Solution {
     2 public:
     3     int candy(vector<int> &ratings)
     4     {
     5         // Note: The Solution object is instantiated only once and is reused by each test case.
     6         int *candyNum = new int[ratings.size()];//每个小孩的糖数目
     7         memset(candyNum,0,sizeof(int)*ratings.size());
     8         int result = candyRecursive(ratings, 0, ratings.size()-1, candyNum);
     9         delete []candyNum;
    10         return result;
    11     }
    12 
    13     int candyRecursive(vector<int> &ratings, int startloc, int endloc,
    14                      int candyNum[])
    15     {
    16         if(startloc == endloc)
    17         {
    18             candyNum[startloc] = 1;
    19             return 1;
    20         }
    21         int middle = (startloc + endloc)/2;
    22         int rightCandy = candyRecursive(ratings, middle+1, endloc, candyNum);
    23         int leftCandy = candyRecursive(ratings, startloc, middle, candyNum);
    24         if(ratings[middle+1] > ratings[middle])
    25         {
    26             int tmp = candyNum[middle+1] - candyNum[middle];
    27             if(tmp <= 0)
    28             {
    29                 tmp *= -1;
    30                 candyNum[middle+1] += (tmp+1);
    31                 rightCandy += (tmp+1);
    32                 for(int i = middle+2; i <= endloc; i++)
    33                 {
    34                     if(ratings[i] > ratings[i-1] && candyNum[i] <= candyNum[i-1])
    35                     {
    36                         int foo = candyNum[i-1] - candyNum[i] + 1;
    37                         candyNum[i] += foo;
    38                         rightCandy += foo;
    39                     }
    40                     else break;
    41                 }
    42             }
    43         }
    44         else if(ratings[middle+1] < ratings[middle])
    45         {
    46             int tmp = candyNum[middle+1] - candyNum[middle];
    47             if(tmp >= 0)
    48             {
    49                 candyNum[middle] += (tmp+1);
    50                 leftCandy += (tmp+1);
    51                 for(int i = middle-1; i >= startloc; i--)
    52                 {
    53                     if(ratings[i] > ratings[i+1] && candyNum[i] <= candyNum[i+1])
    54                     {
    55                         int foo = (candyNum[i+1] - candyNum[i] + 1);
    56                         candyNum[i] += foo;
    57                         leftCandy += foo;
    58                     }
    59                     else break;
    60                 }
    61             }
    62         }
    63         return leftCandy + rightCandy;
    64     }
    65 };

    算法2:初始化所有小孩糖数目为1,从前往后扫描,如果第i个小孩等级比第i-1个高,那么i的糖数目等于i-1的糖数目+1;从后往前扫描,如果第i个的小孩的等级比i+1个小孩高,但是糖的数目却小或者相等,那么i的糖数目等于i+1的糖数目+1。

    该算法时间复杂度为O(N)

    算法2代码如下:

     1 class Solution {
     2 public:
     3     int candy(vector<int> &ratings)
     4     {
     5         // Note: The Solution object is instantiated only once and is reused by each test case.
     6         int *candyNum = new int[ratings.size()];//每个小孩的糖数目
     7         for(int i = 0; i < ratings.size(); i++)
     8             candyNum[i] = 1;
     9         for(int i = 1; i < ratings.size(); i++)
    10             if(ratings[i] > ratings[i-1])
    11                 candyNum[i] = candyNum[i-1] + 1;
    12         for(int i = ratings.size()-2; i>=0; i--)
    13             if(ratings[i] > ratings[i+1] && candyNum[i] <= candyNum[i+1])
    14                 candyNum[i] = candyNum[i+1] + 1;
    15         int result = 0;
    16         for(int i = 0; i < ratings.size(); i++)
    17             result += candyNum[i];
    18         delete []candyNum;
    19         return result;
    20     }
    21 };

     【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3389479.html

  • 相关阅读:
    查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 从SC表中选取score小于60的,并group by sid,having count 大于1
    SQL经典实例书上的数据代码
    mysql练习题
    mysql中alter语句
    如何解决SSH登录Solaris主机速度慢的问题
    Solaris10安装配置LDAP(iPlanet Directory Server )
    Oracle 11g oracle 用户密码过期问题 (ZT)
    Changing Controller Numbers in Solaris
    SPARC T4 RAID Setup (ZT)
    Oracle11g 配置DG broker
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3389479.html
Copyright © 2011-2022 走看看