Medium草稿★★★★★O(n log n) 時間 · O(1) 空間
Two PointersSortingGreedy
Patterns↔️ 雙指針🪙 貪心🔢 排序後處理
尚未複習過

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

881Boats to Save PeopleTwo PointersMediumTwo Pointers

每艘船最多載兩人,且有重量上限 limit。給定每個人的體重 people,回傳載完所有人所需的最少船數。

Example:

Input: people = [3,2,2,1], limit = 3 Output: 3([1,2], [2], [3])

Intuition

TIP

核心思路:排序後,最重的人嘗試與最輕的人配對上同一艘船。若無法配對,最重的人獨自一船。

Approaches

1. Sort + Pairwise (brute-force idea) — O(n²) / O(n)
  • Idea: 排序後嘗試為每個人找配對,用 visited 標記
  • Time: O(n²) - 最差每人掃一遍
  • Space: O(n) - visited 陣列
Brute Force Code
class Solution {
    fun numRescueBoats(people: IntArray, limit: Int): Int {
        people.sort()
        val used = BooleanArray(people.size)
        var boats = 0
        for (i in people.indices.reversed()) {
            if (used[i]) continue
            used[i] = true
            boats++
            for (j in 0 until i) {
                if (!used[j] && people[j] + people[i] <= limit) {
                    used[j] = true
                    break
                }
            }
        }
        return boats
    }
}
⭐ 2. Sort + Two Pointers Greedy — O(n log n) / O(1)
  • Idea: 排序後左右指針,嘗試配對最輕和最重的人
  • Time: O(n log n) - 排序主導
  • Space: O(1) - 原地排序
class Solution {
    fun numRescueBoats(people: IntArray, limit: Int): Int {
        people.sort()
        var left = 0
        var right = people.size - 1
        var boats = 0

        while (left <= right) {
            if (people[left] + people[right] <= limit) {
                left++ // 最輕的人也上船
            }
            right-- // 最重的人一定上船
            boats++
        }
        return boats
    }
}

WARNING

注意迴圈條件是 left <= right(包含等號),因為最後一個人自己也需要一艘船。

🔑 Takeaways