【leetcode】 Candy (hard,pick one)

来源:互联网 发布:数据库源码 编辑:程序博客网 时间:2024/06/06 00:07
题目:

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?

解法一:使用贪心算法,先从左到右扫一次,如果ratings[i+1]>ratings[i],那么i+1获得的糖果就比i多一个。若ratings[i+1]小于或者等于ratings[i],则先默认获得一个糖果,先不管具体的值,然后从尾到头再使用一次贪心,如果ratings[i-1]>ratings[i],则i-1获得的糖果数是i获得的糖果数加1和之前那次贪心留下来的值比较,取最大值。最后将sum求和则解出。

代码

class Solution {
public:
    int candy(vector<int>& ratings) {
        int a[ratings.size()]={0};
        if(ratings.size()==1)
        return 1;
        for(int i=0;i<ratings.size();i++)
        a[i]=1;
        int n=ratings.size();
        
        for(int i=0;i<n-1;i++)
        {
            if(ratings[i+1]>ratings[i])
            {
                a[i+1]=a[i]+1;
            }
        }
        
        for(int i=n-1;i>0;i--)
        {
            if(ratings[i-1]>ratings[i])
            {
                a[i-1]=max(a[i]+1,a[i-1]);
            }
        }
        int sum=0;
        for(int i=0;i<ratings.size();i++)
        {
            sum+=a[i];
            
        }
        return sum;
    }
};

解法二:

由于ratings一定是由非递增数列和非递减数列组成的,若一部分为递增,那么获得的糖果数一定是1,2,3……X,若为递减,则一定是X……3,2,1,如果一个数左边为递增,右边递减,则他应为两边中取较大的一个数。如果相等,则后一个糖果数取默认值为1.

代码:

class Solution {
public:
    int candy(vector<int>& ratings) {
        int a[ratings.size()];
        a[0]=1;
        int candynum=1;
        if(ratings.size()==1)
        return 1;
        int sum=0;
        int n=ratings.size();
        
        for(int i=0;i<ratings.size()-1;)
        {
            if(ratings[i+1]>ratings[i])
            {
                for(i;i<n-1&&ratings[i+1]>ratings[i];i++)
                    sum+=candynum++;
                
                
            }
            else if(ratings[i]==ratings[i+1])
            {
                sum+=candynum;
                i++;
                candynum=1;
               
            }
            else
            {
                int d=1;
                for(i;i<n-1&&ratings[i+1]<ratings[i];i++)
                    {
                        sum+=d++;
                    }
                    sum+=max(d,candynum);
                    
                    candynum=1;sum--;
                    
            }
            
            
            
        }
        sum+=candynum;
        
        
        
  
        return sum;
    }
};


做完遗留的小问题:

第二种算法参考了http://blog.csdn.net/peerlessbloom/article/details/39735575的文章解题思路,虽然觉得第二种方法只遍历了一次vector,但他用时53ms比第一种的36ms还要长,不知道什么原因。

0 0