LeetCode OJ:Candy

来源:互联网 发布:生日祝福html源码 编辑:程序博客网 时间:2024/05/20 17:26

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?

算法思想:

定义数组candy保存第i个孩子分到的糖果数,初始化全为1

找到等级向量数组中最小的元素,从数组中最小的元素开始

1、先往后遍历找到递增顺序的最大的元素,并依次向上累加,最小的元素candy[i]为1,右边比它大的元素candy[i+1]为2,以此类推

2、然后从最大的元素后一个元素(肯定比最大的这个元素小或者相等)开始,向后找到递减顺序最小的元素,如果下标值大于数组长度,退出循环。

以这个最小的元素作为基准点,向左依次向上累加,注意当递减到这个最大元素时,一定是取这个元素当前的值和依次递减累加求的的值得最大值,

否则值取得小了,前面的依次递增顺序求得的值就被破坏了。然后以这个最小元素开始,转入1执行;

3、再往前遍历找到递减顺序最大的元素,并依次向上累加;

4、然后从最大的元素前一个元素(肯定比最大的这个元素小或者相等)开始,向前找到递减顺序最小的元素,如果下标小于0,退出循环;

以这个最小元素作为基准点,向右依次向上累加,然后从这个最小元素开始,转入3执行;

最后将candy数组遍历求和,即得最小的糖果数。

class Solution{public:int ajustRight(vector<int> &ratings,int *candy,int k,int n){//向右递增顺序调整,返回的是最大元素的后一个元素int i=k+1;while(i<n&&ratings[i]>ratings[i-1]){candy[i]=candy[i-1]+1>candy[i]?candy[i-1]+1:candy[i];i++;}return i;}int ajustLeft(vector<int> &ratings,int *candy,int k){//向左递增顺序调整,返回最大元素前一个元素int i=k-1;while(i>=0&&ratings[i]>ratings[i+1]){candy[i]=candy[i+1]+1>candy[i]?candy[i+1]+1:candy[i];i--;}return i;}int findLMin(vector<int> &ratings,int k){//向左找最小的元素int i=k;while(i-1>=0){if(ratings[i-1]<ratings[i])i--;else break;}return i;}int findRMin(vector<int> &ratings,int k,int n){//向右找最小的元素int i=k;while(i+1<n){if(ratings[i+1]<ratings[i])i++;else break;}return i;}void ajust(vector<int> &ratings,int *candy,int k,int n){candy[k]=1;int t=k,h,minV;while(1){h=ajustRight(ratings,candy,t,n);//向右递增调整if(h>=n)break;minV=findRMin(ratings,h,n);//找到右边最小元素candy[minV]=1;ajustLeft(ratings,candy,minV);//向左递增调整t=minV;}t=k;while(1){int h=ajustLeft(ratings,candy,t);//向左递增调整if(h<0)break;minV=findLMin(ratings,h);//找到左边最小元素candy[minV]=1;ajustRight(ratings,candy,minV,n);//向右递增调整t=minV;}}int candy(vector<int> &ratings){int minR=0x7fffffff;int n=ratings.size();int *candy=new int[n];for(int i=0;i<n;i++)candy[i]=1;int index;for(int i=0;i<n;i++){if(minR>=ratings[i]){minR=ratings[i];index=i;//找寻最小元素下标}}ajust(ratings,candy,index,n);int sum=0;for(int i=0;i<n;i++)sum+=candy[i];return sum;}};
answer2:
迭代
时间O(n),空间O(n)
class Solution {public:    int candy(vector<int> &ratings) {        const int n=ratings.size();        vector<int> increment(n);        //左右各扫描一遍        for(int i=1,inc=1;i<n;++i){            if(ratings[i]>ratings[i-1])                increment[i]=max(inc++,increment[i]);            else inc=1;        }                for(int i=n-2,inc=1;i>=0;--i){            if(ratings[i]>ratings[i+1])                increment[i]=max(inc++,increment[i]);            else inc=1;        }                return accumulate(&increment[0],&increment[0]+n,n);    }};

递归 备忘录法
时间O(n),空间O(n)
class Solution {public:    int candy(vector<int> &ratings) {        vector<int> f(ratings.size());        int sum=0;        for(int i=0;i<ratings.size();++i)            sum+=solve(ratings,f,i);        return sum;    }    int solve(const vector<int> &ratings,vector<int>& f,int i){        if(f[i]==0){            f[i]=1;            if(i>0&&ratings[i]>ratings[i-1])                f[i]=max(f[i],solve(ratings,f,i-1)+1);            if(i<ratings.size()-1&&ratings[i]>ratings[i+1])                f[i]=max(f[i],solve(ratings,f,i+1)+1);        }        return f[i];    }};


0 0
原创粉丝点击