Kids With the Greatest Number of Candies

題目描述

給定陣列 candies 和整數 extraCandies,回傳布林陣列,表示每個孩子加上 extraCandies 後是否能擁有最多糖果。

輸入:candies = [2,3,5,1,3], extraCandies = 3
輸出:[true,true,true,false,true]

輸入:candies = [4,2,1,1,2], extraCandies = 1
輸出:[true,false,false,false,false]

解題思路

1

找最大值

用一次 O(n) 掃描找出 candies 中的最大值 maxCandy,作為門檻

2

逐一比較

第二次遍歷,對每個 candies[i] 計算 candies[i] + extraCandies,若 ≥ maxCandy 則為 true

3

回傳結果

收集所有布林值組成結果陣列,長度與 candies 相同

程式碼

C#

csharp
public class Solution {
    public IList<bool> KidsWithCandies(int[] candies, int extraCandies) {
        int maxCandy = candies.Max();
        return candies.Select(c => c + extraCandies >= maxCandy).ToList();
    }
}

TypeScript

typescript
function kidsWithCandies(candies: number[], extraCandies: number): boolean[] {
    const maxCandy = Math.max(...candies);
    return candies.map(c => c + extraCandies >= maxCandy);
}

Python

python
def kidsWithCandies(candies: list[int], extraCandies: int) -> list[bool]:
    max_candy = max(candies)
    return [c + extraCandies >= max_candy for c in candies]

複雜度分析

| | Time | Space | |--|------|-------| | 本解法 | O(n) | O(n) |

找最大值需遍歷一次 O(n),逐一比較再遍歷一次 O(n),合計 O(2n) = O(n)。輸出陣列與輸入等長,空間 O(n)。

邊界情況

圖解

candies: [2,3,5,1,3]
掃描一遍
maxCandy = 5
以 5 為門檻
逐一比較 c+3 >= 5
產生結果
[true,true,true,false,true]

圖表展示兩步驟流程:第一步掃描找到 maxCandy=5,第二步以 5 為門檻逐一判斷。例如 candies[0]=2+3=5 ≥ 5 為 true,candies[3]=1+3=4 不足 5 為 false。

進階觀點

💡面試追問

  • 如果 extraCandies 可以分給不同孩子? 那就變成 combinatorial optimization 問題,需要考慮所有分配方式。若要最大化滿足條件的孩子數,可以用 greedy:優先把糖果分給差距最小的孩子。
  • 能否一次遍歷完成? 不行。必須先知道 maxCandy 才能判斷,而 maxCandy 要掃完整個陣列才知道,所以至少需要兩次遍歷。排序可以一次得到最大值但代價是 O(n log n),不划算。
  • 這題的本質? 就是一個 threshold 判斷。核心 insight 是:額外糖果只給一個孩子,所以只需跟全局最大值比較,不需考慮其他孩子的變化。

理解測驗

🤔 為什麼只需要跟最大值比較就能判斷?

🤔 這題的時間複雜度能比 O(n) 更好嗎?

你可能也想看

1071. Greatest Common Divisor of Strings605. Can Place Flowers

按 ← → 鍵切換課程