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数组[0...ratings.length - 1]

初始化第一个孩子得到一个糖,也就是candy[0] = 1;

从1开始扫描这个ratings数组,

如果遇到上升序列,candy[i] = candy[i - 1] + 1,同时拿一个lastHigh变量记录当前上升序列的index。换句话说,lastHigh存放的就是上一次波峰的峰值的index

如果遇到相等的,candy[i] = 1。这里如果是face2face面试,你应该向面试官询问,如果ratings相等的孩子是否需要拿一样的糖。本题目没有这个要求,所以如果遇到相等的,我们立刻给一个糖,然后更新lastHigh。我第一次想的时候,坚信“lastHigh存放的就是上一次波峰的峰值的index”,所以我认为,“此步骤中,仅当ratings[lastHigh] == ratings[i], 才更新lastHigh为i”。这样,遇到相等的波峰,lastHigh始终指向最后一个高点(悬崖边上:>)。

如果遇到下降序列,这里有点复杂:

1)首先candy[i] = 1,因为要最小数目的糖嘛;

2)然后对从lastHigh + 1 到 i - 1 的candy,我们都要+1,那么,换句话说,total的糖的数目增加了i - lastHigh。注意到这是个优化,我们不需要真实地去遍历candy[lastHigh...i],依次去加1。

3)到了lastHigh,注意由于下降序列可能长度很长,造成candy[lastHigh + 1] == candy[lastHigh],那么,这时候我们也需要增加candy[lastHigh]。否则这一步不用做(candy[lastHigh] > candy[lastHigh + 1)

代码如下:

public int candy(int[] ratings) {
if (ratings.length == 0) {
return 0;
}
int[] candy = new int[ratings.length];
candy[0] = 1;
int lastHigh = 0;
int total = 1;
for(int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
candy[i] = candy[i - 1] + 1;
lastHigh = i;
total += candy[i];
} else if (ratings[i] == ratings[i - 1]) {
candy[i] = 1 ;
if (ratings[lastHigh] == ratings[i]) {//走到波峰的悬崖的边上
lastHigh = i;
}
total += candy[i];
} else {
candy[i] = 1;
total += i - lastHigh; if (i != lastHigh + 1) {
candy[lastHigh + 1]++;
} if (candy[lastHigh] == candy[lastHigh + 1]) {
candy[lastHigh]++;
total += 1;
}
}
}
//assertValid(ratings, candy);
return total;
}

然后,就悲催地发现,超大集合怎么都WA。

然后卡了很久(电影字幕:”十年后。。。“)

楼主把最后一个case的数组下载了下来,一看有9999个元素。只能写了一个文件去读。

因为自信算法上没有什么问题,肯定是什么corner case没考虑到,于是就在算法介绍后面写了个assert 函数去确认candy数组的合法性。主要就是考虑对每个元素,如果ratings大于左右两个邻居,那么candy数组也是如此。不过,我怀疑在判断相等ratings会不会有什么幺蛾子,就同时assert了:对于相等连续的rating元素,他们不能得到candy都一样(否则就不是最小candy数目了啊)。于是发现了这个序列(当前值是i,在3250):

i

ratings:   8116   8116

candy:   2        1         1        0

看出问题了么?lastHigh当时是在9734.

如果继续更新,按照算法,

candy: 3        2          2        1

可是,最小糖,对这个序列来说,应该是:

candy:   2        1         2          1

想了一下,原来lastHigh,不应该是记录波峰的,它的意义应该是:对于当前的i来说,记录能够随意增长而不受到前方其他限制的元素的index。

例如,在上面这个序列中,相等连续序列的最后一个(8116)应该是lastHigh,因为它能够无限制的增长,一满足后面更小的ratings抬高。

所以,上面代码唯一的改动,就是在遇到相等序列的时候,及时更新lastHigh变量。

public int candy(int[] ratings) {
if (ratings.length == 0) {
return 0;
}
int[] candy = new int[ratings.length];
candy[0] = 1;
int lastHigh = 0;
int total = 1;
for(int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
candy[i] = candy[i - 1] + 1;
lastHigh = i;
total += candy[i];
} else if (ratings[i] == ratings[i - 1]) {
candy[i] = 1 ;
lastHigh = i;
total += candy[i];
} else {
candy[i] = 1;
total += i - lastHigh; if (i != lastHigh + 1) {
candy[lastHigh + 1]++;
} if (candy[lastHigh] == candy[lastHigh + 1]) {
candy[lastHigh]++;
total += 1;
}
}
}
//assertValid(ratings, candy);
return total;
}

LeetCode 笔记25 Candy (艰难的调试)的更多相关文章

  1. Leetcode 笔记 36 - Sudoku Solver

    题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...

  2. 程序的载入和运行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25

    程序的载入和运行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文最终把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都 ...

  3. leetcode笔记——35.搜索插入位置 - CrowFea

    0.问题描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 12 输入: [1,3 ...

  4. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  5. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

  6. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  7. Leetcode 笔记 100 - Same Tree

    题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...

  8. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  9. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

随机推荐

  1. 响应式Web设计 – 布局

    写在前面 去年上半年,我开始着手推动项目中响应式设计的落地.以官网优化需求为契机,主动去做了响应式的页面设计,也说服了产品.设计和开发的相关同事一起把它上线落实,但不幸的是,由于各种方面的原因,比如, ...

  2. jQuery 插件开发文章收集

    A jQuery plugin boilerplate http://jonathannicol.com/blog/2012/05/06/a-jquery-plugin-boilerplate/ jQ ...

  3. Centos7安装配置gitlab

    Centos7安装配置gitlab 这篇文字我会介绍在Centos7上安装gitlab,配置gitlab的smtp,并且创建项目demo. sudo yum install openssh-serve ...

  4. 关于Javascript中的复制

    在做项目时有一个需求,是需要复制内容到剪切板,因为有众多浏览器,所以要兼容性很重要 1.最简单的copy,只能在IE下使用 使用clipboardData方法 <script type=&quo ...

  5. Swing应用开发实战系列之一:自定义JdbcTemplate

    笔者本人真正意义上接触编程开发是在2004年,最早用的就是VB,然后是Delphi等,后来转到.Net,中间断断续续还用过PowerBuilder等,无一例外,所研发设计的项目或系统都是WinForm ...

  6. 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点

    平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...

  7. Add Binary

    Add Binary https://leetcode.com/problems/add-binary/ Given two binary strings, return their sum (als ...

  8. Android 开发框架

    Android 开发框架包括基本的应用功能开发.数据存储.网络访问三大块. 1 应用方面 一般而言,一个标准的Android 程序包括Activity.Broadcast Intent Receive ...

  9. cri-o 与 cni的集成分析

    // 创建pod时,network的设置 1.// cri-o/server/sandbox.go // RunPodSandbox creates and runs a pod-level sand ...

  10. python中BeautifulSoup库中find函数

    http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#contents 简单的用法: find(name, at ...