题目:

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?

链接: http://leetcode.com/problems/candy/

题解:

贪婪法,O(n) space的比较简单,可以左右各来一遍,然后加起来。 不过要尝试更好的公司,还需要练习O(1) space的解法。二刷时再解决。

Time Complexity - O(n),Space Complexity - O(n)。

public class Solution {
public int candy(int[] ratings) {
if(ratings == null || ratings.length == 0)
return 0;
int len = ratings.length;
int[] candies = new int[len];
candies[0] = 1; for(int i = 1; i < len; i++) {
if(ratings[i] > ratings[i - 1])
candies[i] = candies[i - 1] + 1;
else
candies[i] = 1;
} int sum = candies[len - 1]; for(int i = len - 2; i >= 0; i--) {
if(ratings[i] > ratings[i + 1])
if(candies[i] <= candies[i + 1])
candies[i] = candies[i + 1] + 1;
sum += candies[i];
} return sum;
}
}

二刷:

依然用的是O(n) space的解法,左右各来一遍。

Java:

public class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0) return 0;
int len = ratings.length;
int[] candys = new int[len];
candys[0] = 1; for (int i = 1; i < len; i++) {
if (ratings[i] > ratings[i - 1]) {
candys[i] = candys[i - 1] + 1;
} else {
candys[i] = 1;
}
} for (int i = len - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1] && candys[i] <= candys[i + 1]) {
candys[i] = candys[i + 1] + 1;
}
} int sum = 0;
for (int count : candys) sum += count;
return sum;
}
}

O(1) space的方法来自Discuss里的@shpolsky

  1. 这里我们一次遍历数组, 主要使用一个变量countDown来记录遍历时遇到的递减序列
  2. 当ratings[i] < ratings[i - 1]时,我们遇到的就是递减序列,这时我们countDown增加一,
  3. 否则,ratings[i] >= ratings[i - 1],大于或者等于这两种情况里,我们都需要对之前遇到的递减情况进行处理
    1. 处理之前含有递减序列的情况
      1. 这里我们用prev这个变量记录了递减序列排头元素peak,有多少块糖
      2. 然后我们利用等差数列求和公式来计算这整个递减序列里我们需要补发多少块糖,countDown是长度n,也是最后一个元素an
      3. 之后还要判断,当countDown >= peak的时候,就是这个递减序列里,需要最多块糖的元素和peak的当前糖数比较,假如peak的糖数少,我们要给peak补充countDown - prev + 1块糖,或者理解为把peak所在位置的糖数从 prev 替换为 countDown + 1。
    2. 接下来我们处理一般情况,就是 ratings[i] = ratings[i - 1]时,prev为1,否则prev加1,我们再把prev添加到结果total中
  4. 最后也要判断一下,是否数组最后的一部分为递减序列,假如是,则按照之前的代码处理。
  5. 返回结果。
public class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0) return 0;
int total = 1, prev = 1, countDown = 0; for (int i = 1; i < ratings.length; i++) {
if (ratings[i] >= ratings[i - 1]) {
if (countDown > 0) {
total += countDown * (countDown + 1) / 2;
if (countDown >= prev) total += countDown - prev + 1;
countDown = 0;
prev = 1;
}
prev = (ratings[i] == ratings[i - 1]) ? 1 : prev + 1;
total += prev;
} else countDown++;
} if (countDown > 0) {
total += countDown * (countDown + 1) / 2;
if (countDown >= prev) total += countDown - prev + 1;
} return total;
}
}

Reference:

https://leetcode.com/discuss/76/does-anyone-have-a-better-idea

https://leetcode.com/discuss/43581/solutions-given-explanation-time-with-space-other-with-space

https://leetcode.com/discuss/16463/a-simple-solution

https://leetcode.com/discuss/8501/my-accepted-o-n-o-1-solution

https://leetcode.com/discuss/23835/one-pass-constant-space-java-solution

135. Candy的更多相关文章

  1. LeetCode 135 Candy(贪心算法)

    135. Candy There are N children standing in a line. Each child is assigned a rating value. You are g ...

  2. leetcode 135. Candy ----- java

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  3. Leetcode#135 Candy

    原题地址 遍历所有小孩的分数 1. 若小孩的分数递增,分给小孩的糖果依次+12. 若小孩的分数递减,分给小孩的糖果依次-13. 若小孩的分数相等,分给小孩的糖果设为1 当递减序列结束时,如果少分了糖果 ...

  4. (LeetCode 135) Candy N个孩子站成一排,给每个人设定一个权重

    原文:http://www.cnblogs.com/AndyJee/p/4483043.html There are N children standing in a line. Each child ...

  5. [leet code 135]candy

    1 题目 There are N children standing in a line. Each child is assigned a rating value. You are giving ...

  6. 【LeetCode】135. Candy

    Candy There are N children standing in a line. Each child is assigned a rating value. You are giving ...

  7. 135. Candy(Array; Greedy)

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  8. Java for LeetCode 135 Candy

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  9. 135 Candy 分配糖果

    There are N children standing in a line. Each child is assigned a rating value.You are giving candie ...

随机推荐

  1. dll不同的调用方式

    LoadLibrary 一般是动态加载DLL时(你并不需要对应的头文件,和LIB) #pragma comment 一般是静态加载DLL时(对应的头文件.DLL,和LIB缺一不可,并且生产的EXE没有 ...

  2. oc语言学习之基础知识点介绍(三):类方法、封装以及继承的介绍

    一.类方法的使用 /* 像我们之前学的方法,必须先实例化这个类的对象才能调用这个方法,类方法不用实例化对象,直接调用这个方法. 之前学的方法调用的语法: [对象名 方法名]; //对象方法 类方法: ...

  3. 再跟SQL谈一谈--高级篇(一)

    1.SELECT KEYWORD ①TOP ②LIKE ③IN ④BETWEEN...AND ⑤ALIAS 2.SELECT JOIN ①JOIN | INNER JOIN ②LEFT JOIN ③R ...

  4. 关于insertBefore

    insertBefore,看名字就是在某个元素前插入元素,但是其实它可以再文档任何元素强势插入. insertBefore用法: parent.insertBefore(newChild, refCh ...

  5. LIS

    五:LIS 概念 最长上升子序列(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列.比如一个序列31 2 6 3 8,他的最长 ...

  6. 学习C++ Primer 的个人理解(十一)

    关联容器 就像是个字典, 其元素是 键 - 值 对. 关键字起到索引作用. 有序: map:关联数组:保存 健-值 对 set : 关键字既是值. multimap : 关键字可重复出现的map mu ...

  7. POJ 1050 To the Max -- 动态规划

    题目地址:http://poj.org/problem?id=1050 Description Given a two-dimensional array of positive and negati ...

  8. 【转】SQL删除重复数据方法

    例如: id           name         value 1               a                 pp 2               a           ...

  9. linux 配置Socks51

    VPN大家耳熟能详,但是socks用到的人比较少,那什么是socks呢?请看第二段或者百度百科,socks分别有4和5两个版本,现在5为主流.工作中经常用VPN访问国外,但是同时国内的速度又慢了,让人 ...

  10. javascript 上传 预览图片 兼容 谷歌 ie

    最近的项目要用到这块,但是在网上找了很多资料,很多都是假的,都不行,最后终于找到一个,还是可以兼容主流的,特分享给大家,可以用 <!DOCTYPE html PUBLIC "-//W3 ...