1. 程式人生 > >Leetcode 135.Candy

Leetcode 135.Candy

Leetcode 135.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?

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.

解法:

這個題的意思大概是在給定優先順序的孩子序列裡,求出需要分發出去的糖的最小數目,且優先順序的孩子要比相鄰優先順序小的孩子獲得的糖多,舉個例子:

例如:現在孩子的優先順序為{1,2,3,4,2,1}

注:由於要讓總糖數最小且每個孩子必須要有一顆糖,所以我們可以初始化將每一個孩子需要的糖數都設為 1,且優先順序大的每次遞增 1

從第一個孩子開始:

  • 第 1 個孩子優先順序為 1 ,需要的糖數為 1
  • 第 2 個孩子優先順序為 2 ,其優先順序大於第 1 個孩子,所以需要的糖數為 1 + 1 = 2
  • 第 3 個孩子優先順序為 3 ,其優先順序大於第 2 個孩子,所以需要的糖數也為 2 +1 = 3
  • 第 4 個孩子優先順序為 4 ,其優先順序大於第 3 個孩子,所以需要的糖數為 3 + 1 = 4

下面問題就出現了:

如果我們按照剛才的演算法繼續從左往右算的話,那麼第 5 個孩子跟第 6 個孩子得到的糖數都會為 1 ,但是這是不對的,因為第 5 個孩子的優先順序要大於第 6 個孩子,所以我們需要

當從左往右掃描完畢之後,再從右往左進行一次上面的操作,也即如果後一個孩子比前一個孩子優先順序低,那麼前一個孩子在後一個孩子的糖數上加一

那麼從後往前算:

  • 第 6 個孩子優先順序為 1 ,需要的糖數為 1
  • 第 5 個孩子優先順序為 2 ,其優先順序大於第 6 個孩子,所以需要的糖數為 1 + 1 = 2
  • 第 4 個孩子優先順序為 4 ,其優先順序大於第 5 個孩子,所以需要的糖數為 2 + 1 = 3

這裡就又出現矛盾了,我們第一次遍歷從左往右算的時候,第四個孩子已經分到了 4 顆糖果,現在從右往左算的時候,反而第四個孩子的糖果數目變少了,這是不對的,所以我們在進行完從左往右搜尋遍歷之後進行從右往左遍歷時候,需要遞增candy[y-1]的時候,可以判斷一下 candy[y] +1 與 candy[y-1]的大小,選用其中比較大的一個數字。


程式碼:

class Solution {
public:
    int candy(vector<int>& ratings) {
        int a[ratings.size()] = {0} ;
        //初始化candy序列
        for(int i = 0 ; i < ratings.size() ; i ++ )
        {
            a[i] = 1 ;
        }
        //從左往右搜
        for(int i = 0 ; i < ratings.size() -1 ; i ++)
        {
            if(ratings[i]<ratings[i+1])
            {
                a[i+1] = a[i] + 1 ;
            }
        }
        //從右往左搜
        for(int i = ratings.size()-1 ; i >=1 ; i -- )
        {
            if(ratings[i-1] > ratings[i] )
            {
                a[i-1] = max( a[i-1] , a[i] + 1 ) ;
            }
        }
        int total = 0 ;
        for(int i = 0 ; i < ratings.size() ; i ++ )
        {
            total = total + a[i] ;
        }
        return total ;
    }
};