LeetCode 力扣 135 分發糖果

2021-10-05 13:20:26 字數 4521 閱讀 9158

給 n 個小朋友分糖,每個人至少有一顆糖。並且有乙個rating陣列,如果小朋友的rating比它旁邊小朋友的rating大(不包括等於),那麼他必須要比對應小朋友的糖多。問至少需要分配多少顆糖。

-表示糖,舉幾個例子。

102

----

-總共就需要 5 顆糖。12

2---

-總共就需要 4 顆糖。

根據題目,首先每個小朋友會至少有乙個糖。

如果當前小朋友的rating比後乙個小朋友的小,那麼後乙個小朋友的糖肯定是當前小朋友的糖加1

比如ration = [ 5, 6, 7],那麼三個小朋友的糖就依次是1 2 3

如果當前小朋友的rating比後乙個小朋友的大,那麼理論上當前小朋友的糖要比後乙個的小朋友的糖多,但此時後乙個小朋友的糖還沒有確定,怎麼辦呢?

參考 32題 的解法五,利用正著遍歷,再倒著遍歷的思想。

首先我們正著遍歷一次,只考慮當前小朋友的rating比後乙個小朋友的小的情況。

接著再倒著遍歷依次,繼續考慮當前小朋友的rating比後乙個小朋友的小的情況。因為之前已經更新過一次糖果了,此時後乙個小朋友的糖如果已經比當前小朋友的糖多了,就不需要進行更新了。

舉個例子

初始化每人乙個糖12

3214

----

--.

只考慮當前小朋友的 rating 比後乙個小朋友的小的情況,後乙個小朋友的糖是當前小朋友的糖加 1。

1<21

2321

4---

----

2<31

2321

4---

----

--3>

2 不考慮

2>

1 不考慮

1<41

2321

4---

----

---

倒過來重新進行

繼續考慮當前小朋友的 rating 比後乙個小朋友的小的情況。此時後乙個小朋友的糖如果已經比當前小朋友的糖多了,就不需要進行更新。41

2321

----

----

--4>

1 不考慮

1<24

1232

1---

----

----

2<

3,3 的糖果已經比 2 的多了,不需要考慮

3>

2,不考慮

2>

1,不考慮

所以最終的糖的數量就是上邊的 - 的和。

**的話,我們用乙個candies陣列儲存當前的分配情況。

public

intcandy

(int

ratings)

//正著進行

for(

int i =

0; i < n -

1; i++)}

//倒著進行

//下標順序就變成了 i i-1 i-2 i-3 ... 0

//當前就是第 i 個,後乙個就是第 i - 1 個

for(

int i = n -

1; i >

0; i--)}

}//計算糖果總和

int sum =0;

for(

int i =

0; i < n; i++

)return sum;

}

時間複雜度:o(n)。

空間複雜度:o(n)。

參考 這裡。

解法一中,考慮到

如果當前小朋友的rating比後乙個小朋友的大,那麼理論上當前小朋友的糖要比後乙個的小朋友的糖多,但此時後乙個小朋友的糖還沒有確定,怎麼辦呢?

之前採用了倒著遍歷一次的方式進行了解決,這裡再考慮另外一種解法。

考慮下邊的情況。

對於第2rating 4,它比後乙個rating要大,所以要取決於再後邊的rating,一直走到2,也就是山底,此時對應的糖果數是1,然後往後走,走回山頂,糖果數一次加1,也就是到rating 4時,糖果數就是3了。

再一般化,山頂的糖果數就等於從左邊的山底或右邊的山底依次加1

所以我們的演算法只需要記錄山頂,然後再記錄下坡的高度,下坡的高度剛好是乙個等差序列可以直接用公式求和。而山頂的糖果數,取決於左邊山底到山頂和右邊山底到山頂的哪個高度大。

而產生山底可以有兩種情況,一種是rating產生了增加,如上圖。還有一種就是rating不再降低,而是持平。

知道了上邊的想法,基本上就可以寫**了,每個人寫出來的應該都不一樣,在discuss區也看到了很多不同的寫法,下邊說一下我的思路。

抽象出四種情況,這裡的高度不是rating進行相減,而是從山底的rating到山頂的rating經過的次數。

左邊山底到山頂的高度大,並且右邊山底後繼續增加。

左邊山底到山頂的高度大,並且右邊山底是平坡。

右邊山底到山頂的高度大,並且右邊山底後繼續增加。

右邊山底到山頂的高度大,並且右邊山底是平坡。

有了這四種情況就可以寫**了。

我們用total變數記錄糖果總和,pre變數記錄前乙個小朋友的糖果數。如果當前的rating比前乙個的rating大,那麼說明在走上坡,可以把前乙個小朋友的糖果數加到total中,並且更新pre為當前小朋友的糖果數。

如果當前的rating比前乙個的rating小,說明開始走下坡,用down變數記錄連續多少次下降,此時的pre記錄的就是從左邊山底到山底的高度。當出現平坡或上坡的時候,將所有的下坡的糖果數利用等差公式計算。此外根據predown決定山頂的糖果數。

根據當前是上坡還是平坡,來更新pre

大框架就是上邊的想法了,還有一些邊界需要考慮一下,看一下**。

public

intcandy

(int

ratings)

else

//當前是上坡,對應情況 1 或者 3

//更新 pre 等於 2

if(ratings[i]

> ratings[i -1]

)else

down =0;

//之前沒有出現過下坡

}else

else}}

else

}//判斷是否有下坡

if(down >0)

else

//將最後乙個小朋友的糖果計算

}else

return total;

}//等差數列求和

private

intcount

(int n)

這個演算法相對於解法一的好處就是將空間複雜度從o(n)優化到了o(1)

解法一雖然空間複雜度大一些,但是很好理解,正著遍歷,倒著遍歷的思想,每次遇到都印象深刻。解法二主要是對問題進行深入考慮,雖然麻煩些,但空間複雜度確實優化了。

更多詳細通俗題解詳見 leetcode.wang 。

力扣刷題筆記 135 分發糖果

題目 135.分發糖果 老師想給孩子們分發糖果,有 n 個孩子站成了一條直線,老師會根據每個孩子的表現,預先給他們評分。你需要按照以下要求,幫助老師給這些孩子分發糖果 每個孩子至少分配到 1 個糖果。相鄰的孩子中,評分高的孩子必須獲得更多的糖果。那麼這樣下來,老師至少需要準備多少顆糖果呢?示例 1 ...

LeetCode 135 分發糖果

老師想給孩子們分發糖果,有 n 個孩子站成了一條直線,老師會根據每個孩子的表現,預先給他們評分。你需要按照以下要求,幫助老師給這些孩子分發糖果 每個孩子至少分配到 1 個糖果。相鄰的孩子中,評分高的孩子必須獲得更多的糖果。那麼這樣下來,老師至少需要準備多少顆糖果呢?示例 1 輸入 1,0,2 輸出 ...

leetcode135 分發糖果

一道很有意思的題目,難度級別為 困難。題目是這樣的的 老師想給孩子們分發糖果,有 n 個孩子站成了一條直線,老師會根據每個孩子的表現,預先給他們評分。你需要按照以下要求,幫助老師給這些孩子分發糖果 每個孩子至少分配到 1 個糖果。相鄰的孩子中,評分高的孩子必須獲得更多的糖果。那麼這樣下來,老師至少需...