Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1899. Merge Triplets to Form Target Triplet - Leetcode Solution

Code Implementation

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];
};
      

Problem Description

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:

  • You can use any triplet at most once (no reuse).
  • You can select any subset of triplets (including none or all).
  • The merged result must match the target triplet exactly (all three values must match).

Return true if it is possible to form the target triplet by merging; otherwise, return false.

Thought Process

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.

Solution Approach

Let's break down the optimized algorithm step by step:

  1. Initialize a marker for each index: Create a list (or array) of three booleans, one for each index, to record whether we've found a "good" triplet for that index.
  2. Iterate through all triplets: For each triplet, check if all its values are less than or equal to their corresponding values in target. If not, skip it (because it would make the merged triplet exceed the target).
  3. Update markers: For each "good" triplet (i.e., one that doesn't exceed the target in any position), if its value at index i equals target[i], set the marker for index i to true.
  4. Check all markers: At the end, if all three markers are 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.

Example Walkthrough

Let's take an example:

  • triplets = [[2,5,3], [1,8,4], [1,7,5]]
  • target = [2,7,5]

Step by step:

  1. Check [2,5,3]: All values ≤ target. It has 2 at index 0 (matches target[0]), so set marker 0 to true.
  2. Check [1,8,4]: 8 > 7 (target[1]), so skip.
  3. Check [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.
Now all three markers are true, so the answer is true.

Time and Space Complexity

Brute-force approach: Checking every subset of triplets would take O(2n) time, which is infeasible for large n.

Optimized approach:

  • Time Complexity: O(n), where n is the number of triplets. We only scan the list once and do constant work per triplet.
  • Space Complexity: O(1), since we only use a fixed-size array (three booleans) regardless of input size.

Summary

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.