Taro Logo

Merge Triplets to Form Target Triplet

Medium
Google logo
Google
1 view
Topics:
Arrays

A triplet is an array of three integers. You are given a 2D integer array triplets, where triplets[i] = [a<sub>i</sub>, b<sub>i</sub>, c<sub>i</sub>] describes the i<sup>th</sup> triplet. You are also given an integer array target = [x, y, z] that describes the triplet you want to obtain.

To obtain target, you may apply the following operation on triplets any number of times (possibly zero):

  • Choose two indices (0-indexed) i and j (i != j) and update triplets[j] to become [max(a<sub>i</sub>, a<sub>j</sub>), max(b<sub>i</sub>, b<sub>j</sub>), max(c<sub>i</sub>, c<sub>i</sub>)].

    • For example, if triplets[i] = [2, 5, 3] and triplets[j] = [1, 7, 5], triplets[j] will be updated to [max(2, 1), max(5, 7), max(3, 5)] = [2, 7, 5].

Return true if it is possible to obtain the target triplet [x, y, z] as an element of triplets, or false otherwise.

For example:

triplets = [[2,5,3],[1,8,4],[1,7,5]], target = [2,7,5] should return true

triplets = [[3,4,5],[4,5,6]], target = [3,2,5] should return false

triplets = [[2,5,3],[2,3,4],[1,2,5],[5,2,3]], target = [5,5,5] should return true

Solution


Clarifying Questions

When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:

  1. What is the range of values for the integers within the triplets, and can they be negative or zero?
  2. Can the `triplets` array be empty, or can any of the individual triplets within it be null or empty?
  3. If it is impossible to form the target triplet, what should the function return? Should I return `false`, throw an exception, or return a special value?
  4. Are duplicate triplets allowed in the `triplets` array, and if so, should they be treated as distinct triplets or combined?
  5. If multiple triplets can be merged to form the target triplet, is it sufficient to find any combination, or is there a specific combination that should be preferred (e.g., the combination with the fewest triplets)?

Brute Force Solution

Approach

The core idea is to examine every possible combination of triplets to see if they can be combined to form the target. We'll go through each triplet individually and see if it helps us get closer to the target triplet.

Here's how the algorithm would work step-by-step:

  1. Look at the first triplet.
  2. Check if this triplet has values that are each less than or equal to the corresponding values in the target triplet.
  3. If it does, consider it as a 'good' triplet.
  4. Move on to the next triplet and do the same check.
  5. Keep going until you've checked all triplets to identify all the 'good' triplets.
  6. Now, see if there is any combination of these 'good' triplets where the largest value in each position matches the target triplet values.
  7. If you find such a combination, then the target triplet can be formed. If you go through all combinations and can't find one, then it cannot.

Code Implementation

def merge_triplets(triplets, target):
    good_triplets = []
    
    for triplet in triplets:
        #Check that each value in the triplet is 
less than or equal to its target counterpart
        if triplet[0] <= target[0] and \
           triplet[1] <= target[1] and \
           triplet[2] <= target[2]:
            good_triplets.append(triplet)

    #Iterate through good triplets to form the target
    for i in range(1 << len(good_triplets)):
        merged_triplet = [0, 0, 0]
        for j in range(len(good_triplets)):
            #This triplet is included in the current combination
            if (i >> j) & 1:
                merged_triplet[0] = max(merged_triplet[0], good_triplets[j][0])
                merged_triplet[1] = max(merged_triplet[1], good_triplets[j][1])
                merged_triplet[2] = max(merged_triplet[2], good_triplets[j][2])

        #Check if the merged triplet matches the target
        if merged_triplet == target:
            return True

    return False

Big(O) Analysis

Time Complexity
O(n)The algorithm iterates through the triplets list once. Inside this loop, there are only constant time operations performed: comparing the current triplet's values with the target triplet and potentially updating boolean flags if a triplet contributes to matching a target value. Therefore, the time complexity is directly proportional to the number of triplets, n, resulting in O(n).
Space Complexity
O(1)The provided explanation describes an iterative process that examines triplets one at a time and keeps track of whether certain triplets are 'good'. No additional data structures that scale with the input size (N, the number of triplets) are mentioned for storing the 'good' triplets or intermediate results. The variables used for comparison and iteration contribute to constant space. Therefore, the auxiliary space used by this algorithm is constant and does not depend on the number of input triplets.

Optimal Solution

Approach

The goal is to see if we can construct a target triplet by merging elements from a list of other triplets. Instead of trying to combine triplets in every possible way, we strategically select the ones that can contribute to the target without exceeding it in any dimension.

Here's how the algorithm would work step-by-step:

  1. Go through each given triplet.
  2. For each triplet, check if all its elements are less than or equal to the corresponding elements in the target triplet.
  3. If a triplet meets the condition above, check if it has at least one element equal to the corresponding element in the target triplet.
  4. If we find three triplets that each have one element matching the target at each of the three positions and also meets the initial condition, then we can form the target triplet.
  5. If, after checking all given triplets, we cannot find such a combination of triplets, it is impossible to form the target triplet.

Code Implementation

def merge_triplets(triplets, target):
    achieved_first = False
    achieved_second = False
    achieved_third = False

    for triplet in triplets:
        if triplet[0] <= target[0] and triplet[1] <= target[1] and triplet[2] <= target[2]:

            # Mark if the triplet can contribute to the target.
            if triplet[0] == target[0]:
                achieved_first = True

            if triplet[1] == target[1]:
                achieved_second = True

            if triplet[2] == target[2]:
                achieved_third = True

    # Need to ensure all elements can be formed.
    if achieved_first and achieved_second and achieved_third:
        return True
    else:
        return False

Big(O) Analysis

Time Complexity
O(n)The algorithm iterates through the list of triplets once. For each triplet, it performs a constant number of comparisons to check if the triplet is suitable and if it contributes to matching the target. The number of triplets is denoted by n. Therefore, the time complexity is directly proportional to n, resulting in O(n).
Space Complexity
O(1)The described solution iterates through the input triplets and uses a fixed number of boolean variables (or similar) to track whether a triplet that contributes to each dimension of the target has been found. No additional data structures are created that scale with the number of triplets (N). Therefore, the auxiliary space used is constant regardless of the input size.

Edge Cases

CaseHow to Handle
Null or empty triplets arrayReturn false immediately as no triplets are available to merge.
Null or empty target tripletReturn false as there is no target to achieve.
Triplets array contains empty tripletsIgnore these triplets during the iteration, effectively skipping them.
Triplets or target contains negative numbersThe algorithm should handle negative numbers correctly if the comparison is based on <=, or explicitly check if all numbers are non-negative.
Very large triplets arrayEnsure the algorithm has a linear time complexity, such as O(n), to scale efficiently by avoiding nested loops.
Target triplet values are larger than the maximum values in the triplets arrayReturn false, as no combination of triplets can achieve a target greater than the individual components.
A triplet has a value greater than corresponding target value, but fails on othersDiscard the triplet because it doesn't contribute to forming the target; it has to be less than or equal on all indices.
No combination of triplets meets all conditions to match the targetReturn false after iterating through all triplets without finding a valid combination.