leetcode candy分糖果问题 两次遍历和一次遍历
2017-12-18 22:51
369 查看
here 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?
就是有一群小孩(数组),数组中每个值代表一个等级,每个小孩必须有一颗糖,相邻的两个小孩中等级高的比等级低的糖多,求如何使得分出去的糖果最少
数组rating :2,4,3,2
分糖果:1,3,2,1
两次遍历:
先从头开始,后面大的比前面多一个
一次遍历:利用等差数列
prev表示的是孩子分的糖果,不断更行。countDown表示的是右边孩子的等级比左边低的孩子个数。
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?
就是有一群小孩(数组),数组中每个值代表一个等级,每个小孩必须有一颗糖,相邻的两个小孩中等级高的比等级低的糖多,求如何使得分出去的糖果最少
数组rating :2,4,3,2
分糖果:1,3,2,1
两次遍历:
先从头开始,后面大的比前面多一个
public int candy(int[] ratings) { int size = ratings.length; if (size == 0) return -1; if (size == 1) return 1; int[] cans = new int[size]; cans[0] = 1; //正向扫描一遍,如果右边的rating比左边高,那么右边的糖果数就比左边多一个,否则只给一个糖果 for (int i = 1; i < size; i++) { if (ratings[i] > ratings[i - 1]) cans[i] = cans[i - 1] + 1; else cans[i] = 1; } //反向扫描一遍,如果左边的rating比右边高,并且左边的糖果数比右边少,那么左边的糖果数应比右边多一 for (int i = size - 2; i >= 0; i--) { if (ratings[i] > ratings[i + 1] && cans[i] <= cans[i + 1]) { cans[i] = cans[i + 1] + 1; } } int ret = 0; //实际上这里可以把ret在上面一个循环中加,减少一次循环,不过本文主要是来实现一次循环,这个简单,大家都会 for (int i = 0; i < size; i++) { ret += cans[i]; } return ret; }
一次遍历:利用等差数列
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; // 1+2+3+4=(1+4)*4/2 if (countDown >= prev) total += countDown - prev + 1;//如果,连续的等级下降的孩子个数,大于这个下降孩子序列之前的那个孩子的分的糖果数,需要对那个孩子,再加糖果 countDown = 0; prev = 1; } prev = ratings[i] == ratings[i-1] ? 1 : prev+1;//比较当前i位置处值和前面的i-1处,是否相等,不等,则需要比i-1处多一个糖果 total += prev; } else countDown++; } if (countDown > 0) { // if we were descending at the end total += countDown*(countDown+1)/2; if (countDown >= prev) total += countDown - prev + 1; } return total; }
prev表示的是孩子分的糖果,不断更行。countDown表示的是右边孩子的等级比左边低的孩子个数。
相关文章推荐
- URL编码(汉字)后提交给后台相关问题,为什么后台有时候解码一次,有时候解码两次
- Hadoop提供的reduce函数中Iterable 接口只能遍历一次的问题
- Reservoir Sampling 蓄水池抽样 海量数据不知道总数只能遍历一次随机抽样问题
- Hadoop提供的reduce函数中Iterable 接口只能遍历一次的问题
- 蓄水池抽样 海量数据不知道总数只能遍历一次随机抽样问题
- 快速两次单击事件导致两次单击事件和一次单击事件的产生问题的处理
- 有关于用javaScript点击一次提交数据却发送了两次或者多次的问题
- 值得注意的算法问题,“两次减法操作”竟然比“一次2倍乘法和一次加法”要慢一秒
- spring定时器一次调用却触发了两次问题分析
- 关于nodejs 假设httpserver,会发现一次网页打开,服务端会响应两次的问题;
- 按钮的ajax请求时,一次点击两次提交的问题
- 值得注意的算法问题,“两次减法操作”竟然比“一次2倍乘法和一次加法”要慢一秒
- 树的遍历 迭代算法——思路:初始化stack,pop stack利用pop的node,push new node to stack,可以考虑迭代一颗树 因为后序遍历最后还要要访问根结点一次,所以要访问根结点两次是难点
- 使用iscroll滑动区域内的div onclick事件单击一次触发了两次问题的解决
- 二元最近的共同祖先问题(O(n) time 而且,只有一次遍历,O(1) Space (它不考虑函数调用栈空间))
- 点击按钮一次,请求两次问题解决
- 有关单链表的两个问题【遍历一次求中间节点,倒数第K个结点】
- [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
- 按钮的ajax请求时,一次点击两次提交的问题
- 每天一道LeetCode-----买卖商品问题,计算最大利润,分别有一次交易,两次交易,多次交易的情况