感觉这道题很有趣。一开始的想法没有经过深入的思考,总是想当然,自然也就容易出错。后来深入思考题中提出的两个条件,想到一个局部极小这个概念,接下来的想法,就显得很自然而然。
总的来说是先DP,然后根据DP的结果决定给每个小孩多少个candies。DP的关键在于定义一个表示子问题的数组变量,在这个题中定义两个这样的变量:
left[i]表示在i的左边,小于ratings[i],且从最近的一个极小值开始连续到i-1(包括i-1),的个数;
right[i]表示在i的右边,小于ratings[i],且从最近的一个极小值开始连续到i+1(包括i+1),的个数;
之后就是决策过程,我觉得把图画出来,一切尽在图中了:
下面是AC代码:
1 /** 2 * There are N children standing in a line. Each child is assigned a rating value. 3 * You are giving candies to these children subjected to the following requirements: 4 * Each child must have at least one candy. 5 * Children with a higher rating get more candies than their neighbors. 6 * What is the minimum candies you must give? 7 * @param ratings 8 * @return 9 */ 10 public int candy(int[] ratings) 11 { 12 int N = ratings.length; 13 int[] candy = new int [N]; //who get how many candies 14 int[] left = new int[N]; //left[i] presents the number of consecutive ratings (in left side of i) smaller than ratings[i] 15 int[] right = new int[N]; //right[i] presents the number of consecutive ratings (in right side of i) smaller than ratings[i] 16 17 //by DP, caculating the left and right 18 left[0] = 0; 19 for(int i=1;i<N;i++) 20 left[i] = ratings[i]>ratings[i-1]? left[i-1]+1:0; 21 right[N-1] = 0; 22 for(int i=N-2;i>=0;i--) 23 right[i] = ratings[i]>ratings[i+1]? right[i+1]+1:0; 24 //decide how many candies each one should get 25 int r = 0; 26 for(int i=0;i<N;i++) 27 { 28 //the local minimum 29 if(left[i] == 0 && right[i] == 0) 30 candy[i] = 1; 31 //the local maximum 32 if(left[i]!=0 && right[i]!=0) 33 candy[i] = Math.max(left[i], right[i])+1; 34 //other cases 35 else 36 candy[i] = left[i]!=0? left[i]+1:right[i]+1; 37 r =r+candy[i]; 38 } 39 return r; 40 }
LeetCode OJ - Candy,布布扣,bubuko.com
原文:http://www.cnblogs.com/echoht/p/3689162.html