您的位置:首页 > 其它

Leetcode: Candy

2014-09-20 13:18 447 查看
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?


Tapping Rain Water问题相似, 用DP。基本思路就是进行两次扫描,一次从左往右,一次从右往左。第一次扫描的时候维护从左到右对于每一个小孩所需要最少的糖果数量,存入数组对应元素中,第二次扫描的时候维护从右到左所需的最少糖果数,并且比较将左边和右边大的糖果数量存入结果数组对应元素中。这样两遍扫描之后就可以得到每一个所需要的最最少糖果量,从而累加得出结果。方法只需要两次扫描,所以时间复杂度是O(2*n)=O(n)。空间上需要一个长度为n的数组,复杂度是O(n)。

public class Solution {
public int candy(int[] ratings) {
if (ratings==null || ratings.length==0) return 0;
int[] left = new int[ratings.length];
int[] right = new int[ratings.length];
int sum = 0;
for (int i=0; i<left.length; i++) {
if (i == 0) left[i] = 1;
else if (ratings[i] > ratings[i-1]) left[i] = left[i-1] + 1;
else left[i] = 1;
}
for (int j=right.length-1; j>=0; j--) {
if (j == right.length-1) right[j] = 1;
else if (ratings[j] > ratings[j+1]) right[j] = right[j+1] + 1;
else right[j] = 1;
}
for (int k=0; k<left.length; k++) {
left[k] = Math.max(left[k], right[k]);
sum += left[k];
}
return sum;
}
}


上面是用两个数组O(2N), 如果只用一个数组O(N),如下所示:

public class Solution {
public int candy(int[] ratings) {
int minNum = 0;
if (ratings==null || ratings.length==0) return minNum;
int[] nums = new int[ratings.length];
for (int k=0; k<nums.length; k++) {
nums[k] = 1;
}
for (int i=1; i<nums.length; i++) {
if (ratings[i] > ratings[i-1]) nums[i] = nums[i-1] + 1;
else if (ratings[i] < ratings[i-1]) nums[i] = 1;
}
for (int i=nums.length-2; i>=0; i--) {
if (ratings[i] > ratings[i+1] && nums[i] <= nums[i+1]) nums[i] = nums[i+1] + 1;
}
for (int i=0; i<nums.length; i++) {
minNum += nums[i];
}
return minNum;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: