[LeetCode][JavaScript]Candy
2015-07-20 19:31
507 查看
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?
https://leetcode.com/problems/candy/
贪心,想通了两轮遍历完事。
第一轮第一个小盆与先给1根,从左往右扫,如果发现当前的rating小于左边的rating,给的糖比左边的多1。
第二轮从倒数第二个小盆与开始,从右往左扫,如果发现当前的rating小于右边的rating,并且糖也少,给的糖比左边的多1。
/** * @param {number[]} ratings * @return {number} */ var candy = function(ratings) { var i, result; rates = []; rates[0] = 1; for(i = 1; i < ratings.length; i++){ if(ratings[i] > ratings[i - 1]){ rates[i] = rates[i - 1] + 1; }else{ rates[i] = 1; } } result = rates[ratings.length - 1]; for(i = ratings.length - 2; i >= 0; i--){ if(ratings[i] > ratings[i + 1] && rates[i] <= rates[i + 1]){ rates[i] = rates[i + 1] + 1; } result += rates[i]; } return result; };
一开始想了一个解法,有点费劲。
第一轮遍历,如果这个小盆与比左右的rating都要小,他肯定是1,把index加入到queue中。
然后就开始递归,有点像bfs。
这样递归的话,保证大的rating一定后做,先处理的是较小的rating。
递归的时候分两种情况:
1. 当前ratings小于左边且大于右边 或者 当前ratings小于右边且大于左边。
因为大的一定后做,所以可以确定当前点的糖数,等于max(左边糖,右边糖) + 1,注意这里如果还没有给过糖,默认值是0,较大的一边是0。
2. 如果两边都给过糖了,并且当前ratings大于左边且大于右边,当前节点的糖数也是等于max(左边糖,右边糖) + 1。
这一轮给完糖后,把左边右边和当前的没有发过糖的节点都塞进queue中。
虽然比较复杂,时间复杂度仍然是O(n)。
但是交上去之后12000的那组数据堆栈溢出。
唉,本地测试10几毫秒妥妥的,leetcode的JS小堆栈居然爆了,是在下输了。
/** * @param {number[]} ratings * @return {number} */ var candyMLE = function(ratings) { var queue = [], result = 0, rates = []; for(var i = 0; i < ratings.length; i++){ if(ratings[i - 1] && ratings[i - 1] < ratings[i]){ continue; } if(ratings[i + 1] && ratings[i + 1] < ratings[i]){ continue; } queue.push(i); result++; rates[i] = 1; } bfs(queue); return result; function bfs(queue){ var len = queue.length; if(queue.length !== 0){ while(len--){ var top = queue.shift(); if(!rates[top]){ giveCandy(queue, top); } if(!rates[top - 1] && ratings[top - 1] && queue.indexOf(top - 1) === -1){ queue.push(top - 1); } if(!rates[top + 1] && ratings[top + 1] && queue.indexOf(top + 1) === -1){ queue.push(top + 1); } if(!rates[top] && queue.indexOf(top) === -1){ queue.push(top); } } bfs(queue); } } function giveCandy(queue, i){ if(ratings[i]){ var leftValue = ratings[i - 1] || 0; var leftRate = rates[i - 1] || 0; var rightValue = ratings[i + 1] || 0; var rightRate = rates[i + 1] || 0; if(ratings[i] > leftValue && ratings[i] < rightValue || ratings[i] < leftValue && ratings[i] > rightValue || ratings[i] >= leftValue && ratings[i] >= rightValue && (leftRate !== 0 || !ratings[i - 1])){ rates[i] = Math.max(leftRate, rightRate) + 1; result += rates[i]; } } } };
相关文章推荐
- extjs 上传文件 fileUpload
- 请问MVC4是不是类似于html页+ashx页之间用JSON通过AJAX交换数据这种方式、?
- Extjs中用dwr实现文件上传时,fileuploadfield不能正常显示的问题
- JS实现HTML地图定位
- 知识储备:JSON数据解析
- web技术发展史
- JavaScript权威指南_131_第15章_脚本化文档_15.6-创建、 插入、删除节点-DocumentFragment
- js去除空格12种方法
- js 跨域问题
- 图解Javascript原型链
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
- json时间转化问题
- js常用函数
- js打印数组查看
- 在jsp界面实现对表单用户名、密码不能为空的验证代码
- [BZOJ1013][JSOI2008]球形空间产生器sphere
- json在线编辑器
- 重写一下js的alert函數
- 欢迎使用CSDN-markdown编辑器
- EasyUI+Javascript+MVC 实现三级级联(一)