class Solution:
def mergeTriplets(self, triplets, target):
found = [False, False, False]
for t in triplets:
if all(t[i] <= target[i] for i in range(3)):
for i in range(3):
if t[i] == target[i]:
found[i] = True
return all(found)
class Solution {
public:
bool mergeTriplets(vector<vector<int>>& triplets, vector<int>& target) {
bool found[3] = {false, false, false};
for (const auto& t : triplets) {
if (t[0] <= target[0] && t[1] <= target[1] && t[2] <= target[2]) {
for (int i = 0; i < 3; ++i) {
if (t[i] == target[i]) found[i] = true;
}
}
}
return found[0] && found[1] && found[2];
}
};
class Solution {
public boolean mergeTriplets(int[][] triplets, int[] target) {
boolean[] found = new boolean[3];
for (int[] t : triplets) {
if (t[0] <= target[0] && t[1] <= target[1] && t[2] <= target[2]) {
for (int i = 0; i < 3; ++i) {
if (t[i] == target[i]) found[i] = true;
}
}
}
return found[0] && found[1] && found[2];
}
}
var mergeTriplets = function(triplets, target) {
let found = [false, false, false];
for (let t of triplets) {
if (t[0] <= target[0] && t[1] <= target[1] && t[2] <= target[2]) {
for (let i = 0; i < 3; ++i) {
if (t[i] === target[i]) found[i] = true;
}
}
}
return found[0] && found[1] && found[2];
};
You are given a list of triplets
, where each triplet is a list of three non-negative integers. You are also given a target
triplet (also three non-negative integers). Your task is to determine if it is possible to select some subset of the given triplets (possibly reordering them), and merge them into a single triplet that exactly equals the target
triplet.
To merge triplets, you choose any number of triplets and, for each index i
(0, 1, 2), take the maximum value at that index among the selected triplets. The result is a new triplet.
The key constraints are:
target
triplet exactly (all three values must match).
Return true
if it is possible to form the target
triplet by merging; otherwise, return false
.
At first glance, one might think about trying every possible subset of triplets, merging them, and checking if the result matches the target
. However, this brute-force approach is very inefficient, especially since there could be up to 1000 triplets, making the number of subsets enormous (2n).
To optimize, let's think about the merging process. Since merging takes the maximum at each index, to reach the target
value at index i
, we must find at least one triplet with target[i]
at that index, and all other entries in that triplet must not exceed the corresponding entries in target
(otherwise, the merged triplet would overshoot the target in some dimension).
Therefore, for each index, we want to find a "good" triplet that has the correct value at that index and does not exceed the target in any dimension. If we can find such a triplet for each index, merging them will give the target.
Let's break down the optimized algorithm step by step:
target
. If not, skip it (because it would make the merged triplet exceed the target).
i
equals target[i]
, set the marker for index i
to true
.
true
, it means we can form the target by merging "good" triplets for each index. Otherwise, it is not possible.
This approach works efficiently because it only needs to scan the list of triplets once and keeps constant-sized state.
Let's take an example:
triplets = [[2,5,3], [1,8,4], [1,7,5]]
target = [2,7,5]
Step by step:
[2,5,3]
: All values ≤ target. It has 2 at index 0 (matches target[0]), so set marker 0 to true.
[1,8,4]
: 8 > 7 (target[1]), so skip.
[1,7,5]
: All values ≤ target. It has 7 at index 1 (matches target[1]) and 5 at index 2 (matches target[2]), so set markers 1 and 2 to true.
true
.
Brute-force approach: Checking every subset of triplets would take O(2n) time, which is infeasible for large n.
Optimized approach:
The key insight is that for each index, we need at least one triplet that matches the target at that index and doesn't exceed the target elsewhere. By scanning all triplets and marking which indices we can "cover" this way, we can efficiently determine if forming the target is possible. This solution is both simple and optimal, and avoids the combinatorial explosion of the brute-force approach.