Hard草稿★★★★★O(n log n) 時間 · O(n) 空間
HeapPriority QueueGreedySorting
Patterns⛰️ 堆・Top-K🪙 貪心🔢 排序後處理
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

502IPOHeap / Priority QueueHardHeap / Priority Queue

假設你有初始資本 w,最多可以完成 k 個專案。每個專案有最低資本需求 capital[i] 和淨利潤 profits[i]。完成專案後利潤加入總資本。選擇最多 k 個專案使得最終資本最大化。

Example:

Input: k = 2, w = 0, profits = [1,2,3], capital = [0,1,1] Output: 4

Intuition

TIP

核心思路:貪心地每次從「當前資本能負擔的專案」中選利潤最高的,用兩個 Heap 管理。

Approaches

1. Brute Force: Scan for Best Affordable Project per Round — O(k·n) / O(n)
  • Idea: 每輪線性掃過所有未做專案,從資本足夠的當中選利潤最高者
  • Time: O(k·n) - k 輪、每輪掃描 O(n)
  • Space: O(n) - used 標記
class Solution {
    fun findMaximizedCapital(k: Int, w: Int, profits: IntArray, capital: IntArray): Int {
        val n = profits.size
        val used = BooleanArray(n)
        var cur = w
        repeat(k) {
            var best = -1
            for (i in 0 until n) {
                if (!used[i] && capital[i] <= cur && (best == -1 || profits[i] > profits[best])) best = i
            }
            if (best == -1) return cur   // 沒有可負擔的專案
            used[best] = true
            cur += profits[best]
        }
        return cur
    }
}
⭐ 2. Two Heaps (Min + Max) — O(n log n) / O(n)
  • Idea: Min Heap 依資本需求排序專案,每輪將可負擔的專案利潤推入 Max Heap,取最大利潤執行
  • Time: O(n log n) - 排序 + heap 操作
  • Space: O(n)
class Solution {
    fun findMaximizedCapital(k: Int, w: Int, profits: IntArray, capital: IntArray): Int {
        val n = profits.size
        val indices = (0 until n).sortedBy { capital[it] }

        val maxHeap = PriorityQueue<Int>(compareByDescending { it })
        var currentCapital = w
        var i = 0

        repeat(k) {
            // 解鎖所有當前資本能負擔的專案
            while (i < n && capital[indices[i]] <= currentCapital) {
                maxHeap.offer(profits[indices[i]])
                i++
            }

            // 選利潤最高的專案
            if (maxHeap.isEmpty()) return currentCapital
            currentCapital += maxHeap.poll()
        }

        return currentCapital
    }
}

🔑 Takeaways