LeetCode135. 分發糖果

Tomorrowland_D發表於2024-07-25

題目連結:https://leetcode.cn/problems/candy/description/

題目敘述:

n 個孩子站成一排。給你一個整數陣列 ratings 表示每個孩子的評分。

你需要按照以下要求,給這些孩子分發糖果:

每個孩子至少分配到 1 個糖果。
相鄰兩個孩子評分更高的孩子會獲得更多的糖果。
請你給每個孩子分發糖果,計算並返回需要準備的 最少糖果數目 。

示例 1:

輸入:ratings = [1,0,2]
輸出:5
解釋:你可以分別給第一個、第二個、第三個孩子分發 2、1、2 顆糖果。

示例 2:

輸入:ratings = [1,2,2]
輸出:4
解釋:你可以分別給第一個、第二個、第三個孩子分發 1、2、1 顆糖果。
第三個孩子只得到 1 顆糖果,這滿足題面中的兩個條件。

提示:

n == ratings.length
1 <= n <= 2 * 10^4
0 <= ratings[i] <= 2 * 10^4

思路

這題我們可以採用貪心的思想,如果想讓所有孩子分到的糖果的總數量最小的話,我們可以先給所有孩子每人發一顆糖果,然後從第二個孩子開始,我們依次與左邊的人進行比較,看看是否比左邊的人評分高

如果比左邊的人評分高的話,我們就把這個孩子的糖果賦值為左邊孩子的糖果數量+1,因為我們一定要比評分低的人的數量至少多1嘛!對吧,所以說我們有了這個式子: candycount[i]=candycount[i-1]+1;

這個階段的程式碼如下:

        vector<int> candycount(ratings.size(),1);
        //跟左邊的孩子進行比較
        for(int i=1;i<ratings.size();i++){
            //比左邊孩子的評分高,那麼我們就將這個地方賦值為左邊孩子糖果數量+1
            if(ratings[i]>ratings[i-1]){
                candycount[i]=candycount[i-1]+1;
            }
        }

解決完左邊以後,我們是不是還沒有滿足題目的要求啊?因為題目說所有孩子要比相鄰兩個孩子分到的糖果數量要多,那麼我們現在只是解決了所有孩子比左邊那個孩子的糖果數量要多,對吧?那麼

我們還需要處理一個邏輯,就是我們要和右邊孩子進行比較,我們如果評分比右邊孩子要高的話,我們就得比右邊的孩子的糖果數量至少要多一個,此時我們賦值的條件就不是簡單的

candycount[i]=candycount[i-1]+1;了,因為我們本身的糖果就有可能比右邊的孩子的糖果數量要多,對吧?所以說我們得取二者中較大的那一個

這段程式碼如下:

       //跟右邊的孩子進行比較
        for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                //這裡得注意了,可能我們比右邊的孩子評分高,但是我們可能本來就比右邊孩子
                //糖果的數量+1就要多,因此我們需要對原本我們糖果的數量和右邊孩子糖果的數量+1
                //這兩個值取一個最大的。
                candycount[i]=max(candycount[i+1]+1,candycount[i]);
            }
        }

做完這兩步以後,我們就能夠保證在評分高的情況下(相較於相鄰兩個孩子),我們就保證了至少比他們的糖果數量要多一個。

整體程式碼如下:

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candycount(ratings.size(),1);
        //跟左邊的孩子進行比較
        for(int i=1;i<ratings.size();i++){
            //比左邊孩子的評分高,那麼我們就將這個地方賦值為左邊孩子糖果數量+1
            if(ratings[i]>ratings[i-1]){
                candycount[i]=candycount[i-1]+1;
            }
        }
        //跟右邊的孩子進行比較
        for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                //這裡得注意了,可能我們比右邊的孩子評分高,但是我們可能本來就比右邊孩子
                //糖果的數量+1就要多,因此我們需要對原本我們糖果的數量和右邊孩子糖果的數量+1
                //這兩個值取一個最大的。
                candycount[i]=max(candycount[i+1]+1,candycount[i]);
            }
        }
        //最後把所有孩子的糖果加起來就行
        int result=0;
        for(int a:candycount) result+=a;
        return result;
    }
};

思考與總結:

這道題目實際上告訴我們一個道理,當我們有左右兩個邊界需要處理時,我們一定不能同時兼顧兩個邊界,這樣就會顧此失彼!最後的結果就是兩邊都得不到想要的結果。

如果這篇文章幫助到你了的話,能不能動動小指頭點個推薦呢?你的推薦就是我更新的最大動力!

相關文章