【LeetCode 135】Candy
阿新 • • 發佈:2018-12-13
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? 題意:給排成一排的小孩發糖,小孩身高有高有矮。對於任何一對相鄰的小孩,兩者相對較高的那個 必須得到比矮個更多的糖。此外必須保證每個人至少得到一塊糖。 求解所需要準備的糖果總數。 Example 1: Input: [1,0,2] Output: 5 Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively. Example 2: Input: [1,2,2] Output: 4 Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively. The third child gets 1 candy because it satisfies the above two conditions.
思路:對於任何一個小孩,他得到的糖要比左右比他矮的小孩的糖更多。這個問題其實與2D蓄水池問題類似,都是和左右比較。所以應該想到從左到右、從右到左各遍歷一遍的方法。此外因為本題僅僅是和相鄰元素對比,所以單調棧用處不大。
發糖的難點其實是當兩相鄰小孩等高時的情況,這時兩人分配的糖果是存在所有可能性的。
先從左到右遍歷,根據rating的大小盡可能少的發糖,即從左到右的發糖只需要滿足兩點: 每個小孩至少一塊糖(所有小孩初始化1塊糖); 左邊小孩較矮的話,右邊小孩的糖數比他多一個。 任何更少的糖果都無法滿足這兩點。再從右到左進行修正,這時候只要滿足一點: 右邊小孩較矮的話,左邊小孩的糖數比他多一個。
int candy(vector<int>& ratings) { int len = ratings.size(); vector<int> candy(len, 1); //left-->right for (int i = 1; i<len; i++) { if (ratings[i]>ratings[i - 1]) candy[i] = candy[i - 1] + 1; } //right-->left and sum int sum = candy[len - 1]; for (int i = len - 2; i >= 0; i--) { if (ratings[i]>ratings[i + 1] && candy[i] <= candy[i + 1]) candy[i] = candy[i + 1] + 1; sum += candy[i]; } return sum; }