You are given a 2D array of integers envelopes where envelopes[i] = [wi, hi] represents the width and the height of an envelope.
One envelope can fit into another if and only if both the width and height of one envelope are greater than the other envelope's width and height.
Return the maximum number of envelopes you can Russian doll (i.e., put one inside the other).
Note: You cannot rotate an envelope.
Example 1:
Input: envelopes = [[5,4],[6,4],[6,7],[2,3]]
Output: 3
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
Example 2:
Input: envelopes = [[1,1],[1,1],[1,1]] Output: 1
Constraints:
1 <= envelopes.length <= 105envelopes[i].length == 21 <= wi, hi <= 105When 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:
The brute force approach to fitting Russian doll envelopes is like trying every single possible arrangement to see which one allows you to fit the most envelopes inside each other. We check every possible nesting order, making sure each envelope can actually fit inside the next.
Here's how the algorithm would work step-by-step:
def max_envelopes_brute_force(envelopes):
number_of_envelopes = len(envelopes)
max_nested_envelopes = 0
for starting_envelope_index in range(number_of_envelopes):
# Consider each envelope as a starting point.
current_max_nested = 1
def can_fit(inner_envelope, outer_envelope):
return inner_envelope[0] < outer_envelope[0] and inner_envelope[1] < outer_envelope[1]
def find_max_nested(current_envelope_index, current_chain_length):
nonlocal current_max_nested
current_max_nested = max(current_max_nested, current_chain_length)
# Explore other envelopes to potentially add to the chain.
for next_envelope_index in range(number_of_envelopes):
if next_envelope_index != current_envelope_index:
if can_fit(envelopes[current_envelope_index], envelopes[next_envelope_index]):
find_max_nested(next_envelope_index, current_chain_length + 1)
find_max_nested(starting_envelope_index, 1)
max_nested_envelopes = max(max_nested_envelopes, current_max_nested)
return max_nested_envelopesThe key idea is to sort the envelopes in a clever way, and then find the longest increasing sequence. This avoids checking every possible combination by focusing on building a valid sequence step-by-step.
Here's how the algorithm would work step-by-step:
def russian_doll_envelopes(envelopes): if not envelopes: return 0 # Sort by width (asc) and height (desc) envelopes.sort(key=lambda x: (x[0], -x[1])) envelope_heights = [envelope[1] for envelope in envelopes] def longest_increasing_subsequence(nums): tails = [] # Iterate through the heights for height in nums: if not tails or height > tails[-1]: tails.append(height) else: # Binary search to find the smallest tail >= height left, right = 0, len(tails) - 1 while left <= right: mid = (left + right) // 2 if tails[mid] < height: left = mid + 1 else: right = mid - 1 tails[left] = height # The length of tails is the LIS length return len(tails)
#Compute the LIS based on heights after sorting
max_envelopes = longest_increasing_subsequence(envelope_heights)
return max_envelopes| Case | How to Handle |
|---|---|
| Input envelopes array is null or empty. | Return 0 if the input array is null or has a length of 0, as no envelopes can be nested. |
| Input envelopes array contains envelopes with zero width or height. | Filter out envelopes with zero width or height as they cannot contain any other envelope. |
| Input envelopes array contains envelopes with negative width or height. | Handle invalid input by throwing an exception or filtering them out since envelope dimensions cannot be negative. |
| All envelopes have the same width. | Sorting by width first breaks the ties with height in descending order ensuring only increasing height is considered for nesting when widths are equal. |
| Envelopes can be nested in multiple valid ways with the same maximum number of nested envelopes. | The longest increasing subsequence algorithm will find one of the valid solutions, which is acceptable. |
| Integer overflow potential during height comparisons if height values are very large. | Use appropriate data types (e.g., long) to avoid potential integer overflow during height comparison. |
| Input array is extremely large. | Ensure the algorithm using binary search for LIS scales efficiently to handle large input sizes. |
| All envelopes have the same width and height | After sorting the envelopes will be in the same order, resulting in a longest increasing subsequence of length 1. |