標籤:
Candy
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?
https://leetcode.com/problems/candy/
貪心,想通了兩輪遍曆完事。
第一輪第一個小盆與先給1根,從左往右掃,如果發現當前的rating小於左邊的rating,給的糖比左邊的多1。
第二輪從倒數第二個小盆與開始,從右往左掃,如果發現當前的rating小於右邊的rating,並且糖也少,給的糖比左邊的多1。
1 /** 2 * @param {number[]} ratings 3 * @return {number} 4 */ 5 var candy = function(ratings) { 6 var i, result; rates = []; 7 rates[0] = 1; 8 for(i = 1; i < ratings.length; i++){ 9 if(ratings[i] > ratings[i - 1]){10 rates[i] = rates[i - 1] + 1;11 }else{12 rates[i] = 1;13 }14 }15 result = rates[ratings.length - 1];16 for(i = ratings.length - 2; i >= 0; i--){17 if(ratings[i] > ratings[i + 1] && rates[i] <= rates[i + 1]){18 rates[i] = rates[i + 1] + 1;19 }20 result += rates[i];21 }22 return result;23 };
一開始想了一個解法,有點費勁。
第一輪遍曆,如果這個小盆與比左右的rating都要小,他肯定是1,把index加入到queue中。
然後就開始遞迴,有點像bfs。
這樣遞迴的話,保證大的rating一定後做,先處理的是較小的rating。
遞迴的時候分兩種情況:
1. 當前ratings小於左邊且大於右邊 或者 當前ratings小於右邊且大於左邊。
因為大的一定後做,所以可以確定當前點的糖數,等於max(左邊糖,右邊糖) + 1,注意這裡如果還沒有給過糖,預設值是0,較大的一邊是0。
2. 如果兩邊都給過糖了,並且當前ratings大於左邊且大於右邊,當前節點的糖數也是等於max(左邊糖,右邊糖) + 1。
這一輪給完糖後,把左邊右邊和當前的沒有發過糖的節點都塞進queue中。
雖然比較複雜,時間複雜度仍然是O(n)。
但是交上去之後12000的那組資料堆疊溢位。
唉,本地測試10幾毫秒妥妥的,leetcode的JS小堆棧居然爆了,是在下輸了。
1 /** 2 * @param {number[]} ratings 3 * @return {number} 4 */ 5 var candyMLE = function(ratings) { 6 var queue = [], result = 0, rates = []; 7 for(var i = 0; i < ratings.length; i++){ 8 if(ratings[i - 1] && ratings[i - 1] < ratings[i]){ 9 continue;10 }11 if(ratings[i + 1] && ratings[i + 1] < ratings[i]){12 continue;13 }14 queue.push(i);15 result++;16 rates[i] = 1;17 }18 bfs(queue);19 return result;20 21 function bfs(queue){22 var len = queue.length;23 if(queue.length !== 0){24 while(len--){25 var top = queue.shift();26 if(!rates[top]){27 giveCandy(queue, top);28 }29 if(!rates[top - 1] && ratings[top - 1] && queue.indexOf(top - 1) === -1){30 queue.push(top - 1);31 }32 if(!rates[top + 1] && ratings[top + 1] && queue.indexOf(top + 1) === -1){33 queue.push(top + 1);34 } 35 if(!rates[top] && queue.indexOf(top) === -1){36 queue.push(top);37 } 38 }39 bfs(queue); 40 }41 }42 function giveCandy(queue, i){43 if(ratings[i]){ 44 var leftValue = ratings[i - 1] || 0;45 var leftRate = rates[i - 1] || 0;46 var rightValue = ratings[i + 1] || 0;47 var rightRate = rates[i + 1] || 0;48 if(ratings[i] > leftValue && ratings[i] < rightValue || 49 ratings[i] < leftValue && ratings[i] > rightValue ||50 ratings[i] >= leftValue && ratings[i] >= rightValue && (leftRate !== 0 || !ratings[i - 1])){51 rates[i] = Math.max(leftRate, rightRate) + 1;52 result += rates[i];53 }54 }55 }56 };
[LeetCode][JavaScript]Candy