135.Candy---贪心
题目大意:分糖果,每个小朋友都有一个ratings值,且每个小朋友至少都要有一个糖果,而且每个小朋友的ratings值如果比左右邻舍的小朋友的ratings值高,则其糖果数量也比邻舍的小朋友多。
法一:超时。按照要求,从前往后比较每个小朋友的ratings值,如果后一个小朋友的ratings值比前一个大,则更新小朋友糖果值dp[i]=dp[i-1]+1;否则,将当前小朋友的糖果值置1,然后考察其前一个小朋友糖果值是否满足dp[i-1]<=dp[i],且ratings[i-1]>ratings[i],如果满足这两个条件,则说明前小朋友的糖果值需要更新,且需要循环遍历更新前面小朋友的糖果值。o(n^2)。代码如下:
public int candy(int[] ratings) {
int len = ratings.length;
if(len == 0) {
return 0;
}
else if(len == 1) {
return 1;
}
int[] dp = new int[len];
//初始化第一个小伙伴的糖果值
dp[0] = ratings[0] <= ratings[1] ? 1 : 2;
int cnt = 0;
for(int i = 1; i < len; i++) {
//只与前面小伙伴的ratings进行比较
if(ratings[i] > ratings[i - 1]) {
dp[i] = dp[i - 1] + 1;
}
else {
dp[i] = 1;
//如果前面小伙伴的糖果是1,且ratings比较高,则遍历其前面的所有小伙伴
if(dp[i - 1] == 1 && ratings[i - 1] > ratings[i]) {
//更新前面的小伙伴的糖果值,因为这个更新,对于这种用例5,3,1,这个小伙伴前面的所有糖果值都要更新,所以进入下面的for循环进行判断
dp[i - 1] = 2;
for(int j = i - 2; j >= 0; j--) {
//如果前面的小伙伴的糖果值小,且ratings又比较高,则更新其值
if(ratings[j] > ratings[j + 1] && dp[j] <= dp[j + 1]) {
dp[j] = dp[j + 1] + 1;
}
else {
break;
}
}
}
}
}
//计算所有的糖果值
for(int i = 0; i < len; i++) {
cnt += dp[i];
}
return cnt;
}
法二(借鉴):两个数组,一个数组从前往后遍历,一旦ratings值比前一个大,则dp[i]=dp[i-1]+1;一个数组从后往前遍历,一旦ratings值比后一个大,则dp[i]=dp[i+1]+1。最后从这两个数组中取一个较大者,计算最终糖果值。o(n)。当然也可以用一个数组,但是思想逻辑都是一样的,只是如果用一个数组的话,就是从后往前遍历得到的新值与当前数组值进行比较,取较大者就是了。代码如下(耗时5ms):
public int candy(int[] ratings) {
int len = ratings.length;
if(len == 0) {
return 0;
}
else if(len == 1) {
return 1;
}
int[] left_candy = new int[len];
int[] right_candy = new int[len];
//初始化
left_candy[0] = ratings[0] <= ratings[1] ? 1 : 2;
right_candy[len - 1] = ratings[len - 1] <= ratings[len - 2] ? 1 : 2;
//从前往后遍历
for(int i = 1; i < len; i++) {
if(ratings[i] > ratings[i - 1]) {
left_candy[i] = left_candy[i - 1] + 1;
}
else {
left_candy[i] = 1;
}
}
//从后往前遍历
for(int j = len - 2; j >= 0; j--) {
if(ratings[j] > ratings[j + 1]) {
right_candy[j] = right_candy[j + 1] + 1;
}
else {
right_candy[j] = 1;
}
}
//两者中取较大者,计算糖果值
int cnt = 0;
for(int i = 0; i < len; i++) {
cnt += Math.max(left_candy[i], right_candy[i]);
}
return cnt;
}
法三(借鉴):最优解。只遍历一遍,o(n)。一旦遍历到递减rating,则计数递减的个数,而暂停计算其糖果值;当遍历到递增rating时,则开始计算前面递减的小朋友的糖果值,以及当前小朋友的糖果值。具体注释看代码。代码如下(耗时5ms):
public int candy(int[] ratings) {
int first = 1, cnt = 0, res = 1, len = ratings.length;
for(int i = 1; i < len; i++) {
//如果比前一个小朋友rating高,则计算总糖果值
if(ratings[i] >= ratings[i - 1]) {
//如果当前小朋友前面有递减rating,先处理这几个小朋友的糖果值
if(cnt > 0) {
//从递减的第二个数开始,到最后一个递减rating结束为止,这几个小朋友的糖果总值就是cnt * (cnt + 1) / 2
res += cnt * (cnt + 1) / 2;
//处理开始递减的第一个数,即将其需要增加的糖果数cnt-res+1,加入res中
if(cnt >= first) {
res += cnt - first + 1;
}
//重置
cnt = 0;
first = 1;
}
//对于当前第i个小朋友,正常计算其糖果值,将其加入res结果中
first = (ratings[i] == ratings[i - 1]) ? 1 : first + 1;
res += first;
}
//计数递减rating的个数
else {
cnt++;
}
}
//处理最后一组递减rating,而其后没有再反弹的小伙伴,即一直递减,不满足ratings[i] >= ratings[i - 1]就到数组终结
if(cnt > 0) {
res += cnt * (cnt + 1) / 2;
if(cnt >= first) {
res += cnt - first + 1;
}
}
return res;
}
135.Candy---贪心的更多相关文章
- LeetCode 135 Candy(贪心算法)
135. Candy There are N children standing in a line. Each child is assigned a rating value. You are g ...
- leetcode 135. Candy ----- java
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- Leetcode#135 Candy
原题地址 遍历所有小孩的分数 1. 若小孩的分数递增,分给小孩的糖果依次+12. 若小孩的分数递减,分给小孩的糖果依次-13. 若小孩的分数相等,分给小孩的糖果设为1 当递减序列结束时,如果少分了糖果 ...
- (LeetCode 135) Candy N个孩子站成一排,给每个人设定一个权重
原文:http://www.cnblogs.com/AndyJee/p/4483043.html There are N children standing in a line. Each child ...
- 135. Candy
题目: There are N children standing in a line. Each child is assigned a rating value. You are giving c ...
- [leet code 135]candy
1 题目 There are N children standing in a line. Each child is assigned a rating value. You are giving ...
- 【LeetCode】135. Candy
Candy There are N children standing in a line. Each child is assigned a rating value. You are giving ...
- 135. Candy(Array; Greedy)
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- Java for LeetCode 135 Candy
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- 135 Candy 分配糖果
There are N children standing in a line. Each child is assigned a rating value.You are giving candie ...
随机推荐
- uoj54-bzoj3434-时空穿梭
题意 在一个 \(n\) 维空间中,求一个点可以用一个 \(n\) 维向量 \((x_1,x_2,\dots x_n)\) 表示.现在要选出 \(c\) 个点,有三个限制: 设 \(x_i\) 表示任 ...
- 【刷题】BZOJ 1095 [ZJOI2007]Hide 捉迷藏
Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...
- [洛谷P4341][BJWC2010]外星联络
题目大意:给你一个长度为$n(n\leqslant3\times10^3)$的字符串,要你求出其中出现次数大于$1$的子串,并按字典序输出次数. 题解:建$SAM$后求出每个点的$size$,最后按字 ...
- HDU 2586 倍增法求lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Windows10实用技巧-固定快捷方式到磁贴菜单方式
快捷方式固定到磁贴 Win10的开始菜单中的磁贴功能比较不错,可以在不清理桌面上其他软件的情况下直接唤醒需要的应用. 但是比较麻烦的是一些应用或快捷方式并不能直接固定到上面. 后来发现所有Windo ...
- STL源码分析归档
1) algorithm 2) traits 3) iterator 4) list 5) function 6) rbtree 7) bitset 8) priority_queue 9) hash ...
- python练习1--用户登入
python版本为python3.51.要求 1)输入用户名密码 2)认证成功后显示欢迎信息 3)输错三次后锁定 2.需求分析 1)用户信息存储在文件中(login/config/user_login ...
- OpenCV---分水岭算法
推文: OpenCV学习(7) 分水岭算法(1)(原理简介简单明了) OpenCV-Python教程:31.分水岭算法对图像进行分割(步骤讲解不错) 使用分水岭算法进行图像分割 (一)获取灰度图像,二 ...
- 【转】手摸手,带你用vue撸后台 系列二(登录权限篇)
前言 拖更有点严重,过了半个月才写了第二篇教程.无奈自己是一个业务猿,每天被我司的产品虐的死去活来,之前又病了一下休息了几天,大家见谅. 进入正题,做后台项目区别于做其它的项目,权限验证与安全性是非常 ...
- kvm虚拟机配置被克隆rhel6客户机的网卡
例子:配置被克隆rhel6客户机的网卡 rhel6的网卡是通过udev规则来进行命名每个网卡都有不一样的macudev规则是根据网卡的mac来进行识别克隆出来的客户机,为了遵守每个网卡的mac都是全球 ...