Medium草稿★★★★★O(n) 時間 · O(1) 空間
Greedy
Patterns🪙 貪心
尚未複習過

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

1899Merge Triplets to Form Target TripletGreedyMediumGreedy

給定一個二維陣列 triplets(每個元素為 [a, b, c])和一個目標 target = [x, y, z]。可以選擇任意兩個 triplets 做 merge(逐位取 max)。判斷是否能透過若干次 merge 得到 target。

Example:

Input: triplets = [[2,5,3],[1,8,4],[1,7,5]], target = [2,7,5] Output: true (選 [2,5,3] 和 [1,7,5] merge 得 [2,7,5])

Intuition

TIP

過濾掉任一維度超過 target 的 triplet(因為 max 只會讓值變大),剩下的看能否湊齊 target 的每一維。

Approaches

1. Brute Force: Check All Subsets — O(2^n) / O(1)
  • Idea: 對所有合法 triplets 的子集嘗試 merge,看是否能得到 target。
  • Time: O(2^n) 最差情況
  • Space: O(1)
class Solution {
    fun mergeTriplets(triplets: Array<IntArray>, target: IntArray): Boolean {
        val valid = triplets.filter {
            it[0] <= target[0] && it[1] <= target[1] && it[2] <= target[2]
        }
        // 嘗試所有子集
        val n = valid.size
        for (mask in 1 until (1 shl n)) {
            val merged = intArrayOf(0, 0, 0)
            for (i in 0 until n) {
                if (mask and (1 shl i) != 0) {
                    for (k in 0..2) merged[k] = maxOf(merged[k], valid[i][k])
                }
            }
            if (merged.contentEquals(target)) return true
        }
        return false
    }
}
⭐ 2. Greedy (Single Pass) — O(n) / O(1)
  • Idea: 過濾合法 triplets 後,只需檢查每個維度是否存在等於 target 的值。用一個 Set 記錄哪些維度已經被滿足。
  • Time: O(n)
  • Space: O(1)
class Solution {
    fun mergeTriplets(triplets: Array<IntArray>, target: IntArray): Boolean {
        val found = BooleanArray(3)
        for (t in triplets) {
            if (t[0] <= target[0] && t[1] <= target[1] && t[2] <= target[2]) {
                for (k in 0..2) {
                    if (t[k] == target[k]) found[k] = true
                }
            }
        }
        return found[0] && found[1] && found[2]
    }
}

🔑 Takeaways