題目地址:here
題目大意:幾個小孩站一排,每個小孩有個等級值,現在給小孩發糖,發的時候要遵守2個規則:(1)每個小孩至少一顆糖(2)兩個相鄰的小孩中,等級大的小孩一定比等級小的小孩糖多,求發糖的數目的最小值。
本文提供兩個算法,第一個是我自己做題時用的,第二個是網上看題解時看到的
算法1:該算法采用分治發,把小孩平均分左右兩撥,求得兩撥小孩的最小值分配方案后,還得看分界線出是否滿足規則。我們用L[end]表示左邊一撥小孩的右邊界,R[start]表示右邊一撥小孩的左邊界,處理分界線出的情況分以下兩種:
(1)如果L[end]等級比R[start]高,但是糖數少或相等,那么就從左邊一撥小孩的右邊界依次調整糖數以滿足規則;
(2)如果L[end]等級比R[start]低,但是糖數多或相等,那么就從右邊一撥小孩的左邊界依次調整糖數以滿足規則;
該算法時間復雜度為O(N*lgN)
算法1代碼如下:
1 class Solution { 2 public: 3 int candy(vector<int> &ratings) 4 { 5 // Note: The Solution object is instantiated only once and is reused by each test case. 6 int *candyNum = new int[ratings.size()];//每個小孩的糖數目 7 memset(candyNum,0,sizeof(int)*ratings.size()); 8 int result = candyRecursive(ratings, 0, ratings.size()-1, candyNum); 9 delete []candyNum; 10 return result; 11 } 12 13 int candyRecursive(vector<int> &ratings, int startloc, int endloc, 14 int candyNum[]) 15 { 16 if(startloc == endloc) 17 { 18 candyNum[startloc] = 1; 19 return 1; 20 } 21 int middle = (startloc + endloc)/2; 22 int rightCandy = candyRecursive(ratings, middle+1, endloc, candyNum); 23 int leftCandy = candyRecursive(ratings, startloc, middle, candyNum); 24 if(ratings[middle+1] > ratings[middle]) 25 { 26 int tmp = candyNum[middle+1] - candyNum[middle]; 27 if(tmp <= 0) 28 { 29 tmp *= -1; 30 candyNum[middle+1] += (tmp+1); 31 rightCandy += (tmp+1); 32 for(int i = middle+2; i <= endloc; i++) 33 { 34 if(ratings[i] > ratings[i-1] && candyNum[i] <= candyNum[i-1]) 35 { 36 int foo = candyNum[i-1] - candyNum[i] + 1; 37 candyNum[i] += foo; 38 rightCandy += foo; 39 } 40 else break; 41 } 42 } 43 } 44 else if(ratings[middle+1] < ratings[middle]) 45 { 46 int tmp = candyNum[middle+1] - candyNum[middle]; 47 if(tmp >= 0) 48 { 49 candyNum[middle] += (tmp+1); 50 leftCandy += (tmp+1); 51 for(int i = middle-1; i >= startloc; i--) 52 { 53 if(ratings[i] > ratings[i+1] && candyNum[i] <= candyNum[i+1]) 54 { 55 int foo = (candyNum[i+1] - candyNum[i] + 1); 56 candyNum[i] += foo; 57 leftCandy += foo; 58 } 59 else break; 60 } 61 } 62 } 63 return leftCandy + rightCandy; 64 } 65 };
算法2:初始化所有小孩糖數目為1,從前往后掃描,如果第i個小孩等級比第i-1個高,那么i的糖數目等於i-1的糖數目+1;從后往前掃描,如果第i個的小孩的等級比i+1個小孩高,但是糖的數目卻小或者相等,那么i的糖數目等於i+1的糖數目+1。
該算法時間復雜度為O(N)
算法2代碼如下:
1 class Solution { 2 public: 3 int candy(vector<int> &ratings) 4 { 5 // Note: The Solution object is instantiated only once and is reused by each test case. 6 int *candyNum = new int[ratings.size()];//每個小孩的糖數目 7 for(int i = 0; i < ratings.size(); i++) 8 candyNum[i] = 1; 9 for(int i = 1; i < ratings.size(); i++) 10 if(ratings[i] > ratings[i-1]) 11 candyNum[i] = candyNum[i-1] + 1; 12 for(int i = ratings.size()-2; i>=0; i--) 13 if(ratings[i] > ratings[i+1] && candyNum[i] <= candyNum[i+1]) 14 candyNum[i] = candyNum[i+1] + 1; 15 int result = 0; 16 for(int i = 0; i < ratings.size(); i++) 17 result += candyNum[i]; 18 delete []candyNum; 19 return result; 20 } 21 };
【版權聲明】轉載請注明出處:http://www.cnblogs.com/TenosDoIt/p/3389479.html