-
Notifications
You must be signed in to change notification settings - Fork 273
Merge Triplets to Form Target Triplet
TIP103 Unit 9 Session 1 (Click for link to problem statements)
- 💡 Difficulty: Medium
- ⏰ Time to complete: 20-30 mins
- 🛠️ Topics: Greedy Algorithms, Arrays
Understand what the interviewer is asking for by using test cases and questions about the problem.
- Established a set (2-3) of test cases to verify their own solution later.
- Established a set (1-2) of edge cases to verify their solution handles complexities.
- Have fully understood the problem and have no clarifying questions.
- Have you verified any Time/Space Constraints for this problem?
-
Q: What does the merge operation do?
- A: It picks two triplets and replaces them with their element-wise maximum, so each of the three positions keeps the larger of the two values.
-
Q: Can a merge ever decrease a value in a triplet?
- A: No. Taking a maximum never makes any position smaller, so once a value exceeds the corresponding target value it can never be brought back down.
-
Q: Do we have to merge every triplet in the list?
- A: No. We may pick which triplets to merge and how many times, so we can simply ignore any triplet that would push a position above the target.
HAPPY CASE
Input: triplets = [[2, 5, 3], [1, 8, 4], [1, 7, 5]], target = [2, 7, 5]
Output: True
Explanation: Merge [2, 5, 3] and [1, 7, 5] to get [max(2,1), max(5,7), max(3,5)] = [2, 7, 5], which equals the target. The triplet [1, 8, 4] is skipped because 8 > 7 would overshoot the second position.
EDGE CASE
Input: triplets = [[3, 4, 5], [4, 5, 6]], target = [3, 2, 5]
Output: False
Explanation: Every triplet has a second value greater than 2, and merging can only keep or raise values, so no sequence of merges can produce a 2 in the second position.
Input: triplets = [[5, 5, 5]], target = [1, 1, 1]
Output: False
Explanation: The only triplet exceeds the target in every position, so no usable triplet exists at all.
Match what this problem looks like to known categories of problems, e.g. Linked List or Dynamic Programming, and strategies or patterns in those categories.
For Building a Target from Choices, we can consider the following approaches:
- Greedy: Because element-wise max only keeps or raises values, it is always safe to merge every triplet that does not exceed the target anywhere. The greedy choice is to take all "safe" triplets and check whether their combined maximum reaches the target.
- Array Scan: A single pass over the list with a running element-wise maximum is enough; no search over merge orders is needed because the max operation is commutative and associative.
Plan the solution with appropriate visualizations and pseudocode.
General Idea:
A triplet is only usable if all three of its values are less than or equal to the corresponding target values — merging it in can then never overshoot. Merge every usable triplet together by tracking a running element-wise maximum, and return whether that merged result equals the target.
1) Initialize a merged triplet as [0, 0, 0].
2) For each triplet [a, b, c] in the list:
a) If a <= target[0] and b <= target[1] and c <= target[2], the triplet is safe to use.
b) Update each position of merged with the max of its current value and the triplet's value.
c) Otherwise, skip the triplet entirely.
3) Return whether merged equals target.
- Merging a triplet that exceeds the target in even one position — a single overshoot can never be undone.
- Requiring one existing triplet to equal the target, instead of letting each of the three target values come from a different safe triplet.
- Trying to simulate actual pairs of merges or explore merge orders; because max is order-independent, one pass with a running maximum is sufficient.
Implement the code to solve the algorithm.
def merge_triplets(triplets, target):
merged = [0, 0, 0]
for a, b, c in triplets:
# Only merge triplets that never exceed the target in any position
if a <= target[0] and b <= target[1] and c <= target[2]:
merged[0] = max(merged[0], a)
merged[1] = max(merged[1], b)
merged[2] = max(merged[2], c)
return merged == list(target)Review the code by running specific example(s) and recording values (watchlist) of your code's variables along the way.
-
Input: triplets = 2, 5, 3], [1, 8, 4], [1, 7, 5, target = [2, 7, 5]
- [2, 5, 3] is safe (2 <= 2, 5 <= 7, 3 <= 5): merged becomes [2, 5, 3].
- [1, 8, 4] is skipped because 8 > 7.
- [1, 7, 5] is safe: merged becomes [2, 7, 5].
- merged equals target. Output: True
-
Input: triplets = 3, 4, 5], [4, 5, 6, target = [3, 2, 5]
- [3, 4, 5] is skipped because 4 > 2.
- [4, 5, 6] is skipped because 4 > 3.
- merged stays [0, 0, 0], which does not equal the target. Output: False
Evaluate the performance of your algorithm and state any strong/weak or future potential work.
Assume N is the number of triplets in the list.
-
Time Complexity:
O(N)because we make a single pass over the list, doing constant work per triplet. -
Space Complexity:
O(1)because we only store the running merged triplet, regardless of input size.