1. 程式人生 > 其它 >Leetcode 455. 分發餅乾(Java實現 超詳細註釋!)

Leetcode 455. 分發餅乾(Java實現 超詳細註釋!)

技術標籤:Leetcode貪心演算法leetcode

Leetcode 455. 分發餅乾

聖誕節發餅乾啦,和昨天的發糖果一樣也是貪心!加了詳細的註釋,方便日後複習,也希望能幫到其他小夥伴,如有錯誤,歡迎指正!

Java實現:

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        // 方法1:貪心+單排序
        /**
        一開始想到的方法,我們貪心地儘量把儘可能小又能滿足孩子的餅乾給該孩子;
        我們可以把餅乾從小到大排序,然後遍歷所有孩子,對於任意一個孩子都先把最小的給它,如果滿足不了,就換大的,
        直到能滿足就說明該孩子滿足了,計數+1、把這塊餅乾刪除並break,如果所有餅乾都滿足不了就跳過這個孩子;
        */
// 因為沒發出一塊餅乾都需要刪除餅乾,陣列刪除比較麻煩,所以我們把陣列轉成ArrayList ArrayList<Integer> cookie_size = new ArrayList<Integer>(); // 把餅乾從小到大排序 Arrays.sort(s); // 把排序後的陣列元素依次存入cookie_size中 for (int i = 0; i < s.length; i++){ cookie_size.add(s[i]); }
// 記錄已滿足孩子的個數 int count = 0; // 遍歷所有孩子 for (int i = 0; i < g.length; i++){ // 對於每一個孩子我們都先把最小的餅乾給它,如果滿足不了,就換大的 for (int j = 0; j < cookie_size.size(); j++){ // 如果滿足了就刪除這塊餅乾、計數+1並結束這個孩子的迴圈 if (g[i] <= cookie_size.get
(j)){ cookie_size.remove(j); count++; break; } } } // 最後返回計數的結果 return count; // 方法2:雙排序+貪心 /**很明顯上面的方法雖然佔用記憶體很少,但是時間複雜度太高,我們必須優化它 我們可以想到的是刪除餅乾其實不是必須的,那我們可以簡化這個刪除餅乾的動作; 一個最簡單的的辦法就是可以跳過那些肯定不滿足的餅乾,但是每一個孩子的需求都不一樣,怎麼跳過呢? 既然每個孩子的需求不一樣,我們是不是可以按照孩子的需求排序呢?我們把孩子的需求從小到大排序,這時候我們再遍歷餅乾的時候, 如果一塊餅乾連左邊的孩子都滿足不了,那這塊餅乾肯定不能滿足右邊的孩子,我們其實就可以跳過這塊餅乾; 此外如果一塊餅乾已經被髮給一個孩子了,那麼我們也可以跳過這塊餅乾;那麼綜合這兩種情況,一塊餅乾被遍歷後無非就這兩種情況,一是被髮給小朋友, 二是不滿足這個小朋友被跳過了,因此只要一塊餅乾被遍歷過,我們就可以跳過這塊餅乾,我們用index來記錄當前剩餘的第一塊餅乾的索引即可, 前面的相當於都被跳過了 */ // 將餅乾和孩子都從小到大排序 Arrays.sort(s); Arrays.sort(g); // 記錄被滿足的孩子的個數 int count = 0; // 記錄當前剩餘的第一塊餅乾的索引 int index = 0; // 遍歷每一個孩子 for (int i = 0; i < g.length; i++){ // 遍歷每一塊餅乾 for (int j = index; j < s.length; j++){ // 遍歷一塊餅乾,就將索引++ index++; // 如果該餅乾滿足該孩子就計數++ if (g[i] <= s[j]){ count++; break; } } } // 最後返回計數的結果 return count; } }