LeetCode 笔记25 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数组[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 (艰难的调试)的更多相关文章
- Leetcode 笔记 36 - Sudoku Solver
题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...
- 程序的载入和运行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25
程序的载入和运行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文最终把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都 ...
- leetcode笔记——35.搜索插入位置 - CrowFea
0.问题描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 12 输入: [1,3 ...
- 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 ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
随机推荐
- 转 Android学习 之 ColorStateList按钮文字变色
Windows平台VC,对于不同的按钮状态,采用不同的颜色显示文字,实现起来比较复杂,一般都得自绘按钮.但是Android里面实现起来非常方便. 我们首先添加一个ColorStateList资源XML ...
- eclipse 导入新项目后报错:Cannot change version of project facet Dynamic web module to 2.5
错误原因: 我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2 ...
- 使用Android studio创建的AIDL编译时找不到自定义类的解决办法
使用AS创建ADIL文件时AS会在main文件夹下给我们生成一个aidl文件夹和一个相同包名的包,通常我们会把所有和ADIL相关的类或文件放在这个包下,但是如果存在自定义的类时,程序编译时无法通过,提 ...
- 集算器协助java处理多样性数据源之MongoDB
MongoDB不支持join,其官网上推荐的unity jdbc可以把数据取出来进行二次计算实现join运算,但这些join.group.函数.表达式等高级功能都是收费版才有,而且即使是收费版本,对子 ...
- 复制文件的bat脚本
数据库备份到不同的机器上的一段脚本 使用系统的copy 命令来复制单个文件 如果要复制某个文件夹,则使用xcopy 命令 set date=%Date:~0,4%%Date:~5,2%%Date:~8 ...
- Dos
一.简介 https://zh.wikipedia.org/wiki/DOS 二.系统下载 http://www.cn-dos.net/newdos/doswarea.htm 三.实用命令 1)查看系 ...
- 初学嵌入式STM32基础下选哪款开发板适合学习
iTOP-4412开发板 目前为止,在用户网盘上已经积累了多达100G以上资料, 这些资料都是和4412相关的,并不是随便拼凑起来的!同时我们也完全开放原厂资料. 鉴于用户对于海量资料无从下手的问题, ...
- OpenXml入门----给Word文档添加表格
下面将展示如何使用Openxm向Word添加表格. 代码中表头和数据我用的同一个TableRow来添加,其实可以通过TableHeader来,其实都一样.后面教程我会给出如何设置单元格样式.表头那一行 ...
- [cocos2dx] 让UIButton支持disable状态
摘要: 主要解决cocos2dx-2.2.2版本中, UIButton显示不了disable状态图的问题. 顺便, 理解了一下cocos2dx中UIWidget的渲染原理. 博客: http://ww ...
- UVALive 6168 Fat Ninjas --二分小数+搜索
题意:一个NxN的网格地板,有一些激光束从天花板垂直射向地面的某个网格,一个圆要安全地从左走到右,不碰到上边界,下边界以及激光束,问这个圆的直径最大能达到多大. 分析:可以二分直径,关键在check函 ...