Candy
来源:互联网 发布:国际长途网络电话软件 编辑:程序博客网 时间:2024/05/29 18:12
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为:1,3,3,4,3,2,1,0;那么candy数量应该为:1+2+2+5+4+3+2+1=20。分析其中的规律,rating相等的两个邻居candy数可以不等,我们只需要关注序列中连续的递减子序列的长度即可,比如本例中的 4,3,2,1,0,到达前四个人1,3,3,4显然我们分别应该给予1,2,3,4个candy,遇到第五个人3时,与前邻居4比是递减的,我们也给它1个,但是此时因为前邻居是4个,故不用加;接下来看2,我们给它1个,前邻居3也是1个,故应该给它加1个,但是前前邻居4是4个,故不用加;以此类推。。。
由上述分析可以看出,我们需要记录递减子序列的长度descLen,以及子序列开头第一个人的candy数量descBegCan,在判断当前属于递减子序列的人的candy数时,我们并不能仅仅给当前candy总数加上这个长度,因为可能递减子序列的开头那个人(仅仅是开头这个人)本身已经有很多candy了,那么它不需要加1(就像上面判断到第五六个人3,2时,我们并不需要给第四个人4的candy数加1,因为它已经有了3个了,3>2>1 成立),而要看当前的长度descLen与descBegCan的大小关系,如果长度小于开头那个人的数量,那么仅加上长度减1 即可;如果二者相等,那么需要加上长度。
其实题目的描述本身就是一个很好的方案:初始化将每个人的糖果数都初始化为1。每次遍历只考虑左右一边,即从左向右遍历,如果i>i-1 则 candy[i]=candy[i-1];再从右向左遍历一次,如果i>i+1 并且 candy[i]<=candy[i+1] 则 cand[i]=candy[i+1]+1; 这样的两次遍历,左右两边都顾及到了。最后将candy[i]相加求和就好了。
class Solution{public: int candy(vector<int> &ratings){ int n=ratings.size(); if(n==1) return 1; int i,sum=0; vector<int> candy(n,1); //先将每人的值都设为1 //从前向后扫描 for(i=1;i<n;i++){ if(ratings[i]>ratings[i-1])candy[i]=candy[i-1]+1; } //从后向前扫描 for(i=n-2;i>=0;i--){ if(ratings[i]>ratings[i+1] && candy[i]<=candy[i+1])candy[i]=candy[i+1]+1; } for(i=0;i<n;i++) sum+=candy[i]; return sum; }};
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- Candy
- candy
- Candy
- Candy
- Candy
- Candy
- linux blkid
- 二叉数组的创建删除插入查找
- STL中stack用法
- gt8105电容屏驱动分析
- KVM虚拟化CPU技术总结
- Candy
- 了解typename的双重意义
- IBM AppScan安全测试一例——跨站脚本攻击
- 使用Gradle提交自己开源Android库到Maven中心库
- Android 事件分发总结
- 文章标题
- 【Java】快速排序
- 比特币『私钥』『公钥』『钱包地址』间的关系
- 蓝牙A2DP的初始化过程