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?
举个例子,1 3 2 7 5 4 2
第一眼我们肯定会想到让一些波谷(1, 3, 2)的糖果个数为1, 然后依次从这些值往左和往右扩张填充。如果只能想到模拟的方法,那这题基本没法做。
这里值得强调的是,一般情况下,面试要考察的都不会是简单的模拟。
除了与左边和右边的邻居比较,我们还能怎么理解这个问题呢?
如果从定序的角度来看,我们可以从左到右和从右到左遍历这个序列,对于每一个位置,它需要的糖果数量与它从某个方向看过来是第几个连续增长的数有关。并且是从左与从右看的结果中取较大。
有了这种“定序”的思想,找到解答的方法也就很简单了。
值得注意的是,在从一个方向往另一个方向扫描的过程中,由于连续相等的数值之间是不做比较的,所以相等的数可以只发一个糖果,作为下一个递增序列的开始。
Code:
class Solution { public: int candy(vector<int> &ratings) { int n = ratings.size(); if(n == 0) return 0; int sum = 0; vector<int> left(n, 1); vector<int> right(n, 1); for(int i = 1; i < n; i++) { if(ratings[i] > ratings[i-1]) left[i] = left[i-1] + 1; else left[i] = 1; // first error, when equal, no camparison, so the candy could start from 1 } for(int j = n-2; j >= 0; j--) { if(ratings[j] > ratings[j+1]) right[j] = right[j+1] + 1; else right[j] = 1; } for(int i = 0; i < n; i++) sum += max(left[i], right[i]); return sum; } };