Medium草稿★★★★★O(n log n) 時間 · O(n) 空間
GreedySorting
Patterns🪙 貪心🔢 排序後處理
尚未複習過

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

1029Two City SchedulingGreedyMediumGreedy

2n 個人要分成兩組,分別飛往城市 A 和城市 B,每組恰好 n 人。costs[i] = [aCost_i, bCost_i] 表示第 i 個人飛往 A 和 B 的費用。回傳最小總費用。

Example:

Input: costs = [[10,20],[30,200],[400,50],[30,20]] Output: 110

Intuition

TIP

按「去 A 比去 B 省多少」排序,前 n 個去 A,後 n 個去 B。

Approaches

1. Sort + Greedy — O(n log n) / O(1)
  • Idea: 按 aCost - bCost 排序,前 n 個去 A、後 n 個去 B。
  • Time: O(n log n)
  • Space: O(1)(排序為原地)
class Solution {
    fun twoCitySchedCost(costs: Array<IntArray>): Int {
        costs.sortBy { it[0] - it[1] }
        val n = costs.size / 2
        var total = 0
        for (i in costs.indices) {
            total += if (i < n) costs[i][0] else costs[i][1]
        }
        return total
    }
}
⭐ 2. As Above + Clearer Derivation — O(n log n) / O(n)
  • Idea: 先假設所有人都去 B,然後計算改去 A 的「節省」,選節省最多的 n 個人改去 A。
  • Time: O(n log n)
  • Space: O(n)
class Solution {
    fun twoCitySchedCost(costs: Array<IntArray>): Int {
        val n = costs.size / 2
        var totalB = 0
        val diff = IntArray(costs.size)

        for (i in costs.indices) {
            totalB += costs[i][1]
            diff[i] = costs[i][0] - costs[i][1] // 改去 A 的額外成本
        }
        diff.sort()

        // 選額外成本最小(最負 = 節省最多)的 n 人改去 A
        var result = totalB
        for (i in 0 until n) {
            result += diff[i]
        }
        return result
    }
}

🔑 Takeaways