1. 程式人生 > >LeetCode Problems #135

LeetCode Problems #135

2018年10月28日

#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.

問題分析:

本題難度為Hard!已給出的函式定義為:

class Solution:
    def candy(self, ratings):
        """
        :type ratings: List[int]
        :rtype: int
        """

其中引數ratings為列表,輸出為int型別;

該題屬於 貪心問題,有很多種解法,這裡採取一種最好理解的方法;本題的題目要求是若一個小孩的評分比相鄰的小孩的評分高,那麼他的所獲得的糖果就必須比相鄰的小孩多,且每個小孩至少獲得一顆糖果,求最少要分配多少顆糖果。

這裡首先考慮一種更簡單一點的情況,即從第一個小孩開始,只要求如果一個小孩的評分比前一個小孩的評分高,則他獲得的糖果比前一個小孩多,這樣每個小孩獲得的糖果都比其 前相鄰 

的小孩獲得的糖果多;這樣只需要遍歷一次ratings,每次遇到小孩的評分比前一個小孩的評分高,則他獲得的糖果是前一個小孩的糖果數加一。

同理,反方向進行判斷,從最後一個小孩開始,若一個小孩的評分比後一個小孩的評分高,則他獲得的糖果比後一個小孩多,這樣每個小孩獲得的糖果都比其 後相鄰 的小孩獲得的糖果多,實現方法同前反向遍歷即可。

這樣將兩種情況結合起來,一個小孩最終獲得的糖果取前相鄰和後相鄰情況的較大值。

程式碼實現:

python3

#coding:utf-8
class Solution:
    def candy(self, ratings):
        """
        :type ratings: List[int]
        :rtype: int
        """
        forward_candy=[1 for i in range(len(ratings))]
        backward_candy=[1 for i in range(len(ratings))]
        final_candy = [0 for i in range(len(ratings))]
       
        for i in range(len(ratings)-1):
            if ratings[i+1]>ratings[i]:  # forward
                forward_candy[i+1]=forward_candy[i]+1
            if ratings[len(ratings)-2-i]>ratings[len(ratings)-1-i]:  # backward
                backward_candy[len(ratings)-2-i]=backward_candy[len(ratings)-1-i]+1

        for i in range(len(forward_candy)): # fianl
            if forward_candy[i]>backward_candy[i]:  
                final_candy[i]=forward_candy[i]    
            else:
                final_candy[i]=backward_candy[i] 
        return sum(final_candy)