给定N个信封,作为{W, H}对,其中W为宽度, H为高度。当且仅当一个信封的宽度和高度都大于另一个信封的宽度和高度时,一个信封可以装入另一个信封。找出可以放入另一个信封的最大信封数量,依此类推。不允许旋转信封。
例子:
Input: envelope[] = {{4, 3}, {5, 3}, {5, 6}, {1, 2}}
Output: 3
Explanation:
The maximum number of envelopes that can be put into another envelope
is 3.
({1, 2}, {4, 3}, {5, 6})
Input: envelope[] = {{3, 6}, {5, 4}, {4, 8}, {6, 9}, {10, 7}, {12, 12}}
Output: 4
Explanation:
The maximum number of envelopes that can be put into another envelope is 4.
({3, 6}, {4, 8}, {6, 9}, {12, 12})
朴素方法:这个问题类似于动态规划的最长递增子序列问题。这个想法是按非递减顺序对信封进行排序,并对每个信封检查可以放入该信封内的信封数量。请按照以下步骤解决问题:
- 按照宽度和高度的非递减顺序对数组进行排序。
- 初始化一个dp[]数组,其中dp[i]存储可以放入的信封数量,其中信封[i]为最大信封。
- 对于每个信封[i],循环遍历小于其自身的信封,并检查较小信封的宽度和高度是否严格小于信封[i]的宽度和高度。如果小于,则可以将较小的信封放入信封[i]内。
- dp[]数组的最大值给出了可以相互放入的信封的最大数量。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that returns the maximum
// number of envelopes that can be
// inserted into another envelopes
int maxEnvelopes(vector > envelopes)
{
// Number of envelopes
int N = envelopes.size();
if (N == 0)
return N;
// Sort the envelopes in
// non-decreasing order
sort(envelopes.begin(),
envelopes.end());
// Initialize dp[] array
int dp[N];
// To store the result
int max_envelope = 1;
dp[0] = 1;
// Loop through the array
for (int i = 1; i < N; ++i) {
dp[i] = 1;
// Find envelopes count for
// each envelope
for (int j = 0; j < i; ++j) {
if (envelopes[i][0] > envelopes[j][0]
&& envelopes[i][1] > envelopes[j][1]
&& dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
}
// Store maximum envelopes count
max_envelope = max(max_envelope,
dp[i]);
}
// Return the result
return max_envelope;
}
// Driver Code
int main()
{
// Given the envelopes
vector > envelopes
= { { 4, 3 }, { 5, 3 }, { 5, 6 }, { 1, 2 } };
// Function Call
cout << maxEnvelopes(envelopes);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Function that returns the maximum
// number of envelopes that can be
// inserted into another envelopes
static int maxEnvelopes(int[][] envelopes)
{
// Number of envelopes
int N = envelopes.length;
if (N == 0)
return N;
// Sort the envelopes in
// non-decreasing order
Arrays.sort(envelopes,
(a, b) -> (a[0] != b[0]) ?
a[0] - b[0] :
a[1] - b[1]);
// Initialize dp[] array
int[] dp = new int[N];
// To store the result
int max_envelope = 1;
dp[0] = 1;
// Loop through the array
for(int i = 1; i < N; ++i)
{
dp[i] = 1;
// Find envelopes count for
// each envelope
for(int j = 0; j < i; ++j)
{
if (envelopes[i][0] > envelopes[j][0] &&
envelopes[i][1] > envelopes[j][1] &&
dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
}
// Store maximum envelopes count
max_envelope = Math.max(max_envelope, dp[i]);
}
// Return the result
return max_envelope;
}
// Driver Code
public static void main (String[] args)
{
// Given the envelopes
int[][] envelopes = { { 4, 3 }, { 5, 3 },
{ 5, 6 }, { 1, 2 } };
// Function call
System.out.println(maxEnvelopes(envelopes));
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Function that returns the maximum
# number of envelopes that can be
# inserted into another envelopes
def maxEnvelopes(envelopes):
# Number of envelopes
N = len(envelopes)
if (N == 0):
return N
# Sort the envelopes in
# non-decreasing order
envelopes = sorted(envelopes)
# Initialize dp[] array
dp = [0] * N
# To store the result
max_envelope = 1
dp[0] = 1
# Loop through the array
for i in range(1, N):
dp[i] = 1
# Find envelopes count for
# each envelope
for j in range(i):
if (envelopes[i][0] > envelopes[j][0]
and envelopes[i][1] > envelopes[j][1]
and dp[i] < dp[j] + 1):
dp[i] = dp[j] + 1
# Store maximum envelopes count
max_envelope = max(max_envelope, dp[i])
# Return the result
return max_envelope
# Driver Code
if __name__ == '__main__':
# Given the envelopes
envelopes = [ [ 4, 3 ], [ 5, 3 ],
[ 5, 6 ], [ 1, 2 ] ]
# Function Call
print(maxEnvelopes(envelopes))
# This code is contributed by Mohit Kumar
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function that returns the maximum
// number of envelopes that can be
// inserted into another envelopes
int maxEnvelopes(vector >& envelopes)
{
// Number of envelopes
int N = envelopes.size();
if (N == 0)
return N;
// Sort the envelopes in increasing
// order of width and decreasing order
// of height is width is same
sort(envelopes.begin(), envelopes.end(),
[](vector& a, vector& b) {
return a[0] < b[0]
or (a[0] == b[0] and a[1] > b[1]);
});
// To store the longest increasing
// sequence of height
vector dp;
// Finding LIS of the heights
// of the envelopes
for (int i = 0; i < N; ++i) {
auto iter = lower_bound(dp.begin(),
dp.end(),
envelopes[i][1]);
if (iter == dp.end())
dp.push_back(envelopes[i][1]);
else if (envelopes[i][1] < *iter)
*iter = envelopes[i][1];
}
// Return the result
return dp.size();
}
// Driver Code
int main()
{
// Given the envelopes
vector > envelopes
= { { 4, 3 }, { 5, 3 }, { 5, 6 }, { 1, 2 } };
// Function Call
cout << maxEnvelopes(envelopes);
return 0;
}
3
时间复杂度: O(N 2 )
辅助空间: O(N)
高效的方法:为了优化朴素的方法,想法是使用二分搜索的概念 和最长递增子序列。如果宽度相同,则按照宽度的递增顺序和高度的递减顺序对信封进行排序,从而将问题减少到找到信封的最长的高度递增序列。这种方法有效,因为宽度已经按递增顺序排序,并且只有最大的高度递增序列才足以找到最大数量的信封。本文讨论了在N×log(N)方法中找到最长递增序列的有效方法。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that returns the maximum
// number of envelopes that can be
// inserted into another envelopes
int maxEnvelopes(vector >& envelopes)
{
// Number of envelopes
int N = envelopes.size();
if (N == 0)
return N;
// Sort the envelopes in increasing
// order of width and decreasing order
// of height is width is same
sort(envelopes.begin(), envelopes.end(),
[](vector& a, vector& b) {
return a[0] < b[0]
or (a[0] == b[0] and a[1] > b[1]);
});
// To store the longest increasing
// sequence of height
vector dp;
// Finding LIS of the heights
// of the envelopes
for (int i = 0; i < N; ++i) {
auto iter = lower_bound(dp.begin(),
dp.end(),
envelopes[i][1]);
if (iter == dp.end())
dp.push_back(envelopes[i][1]);
else if (envelopes[i][1] < *iter)
*iter = envelopes[i][1];
}
// Return the result
return dp.size();
}
// Driver Code
int main()
{
// Given the envelopes
vector > envelopes
= { { 4, 3 }, { 5, 3 }, { 5, 6 }, { 1, 2 } };
// Function Call
cout << maxEnvelopes(envelopes);
return 0;
}
3
时间复杂度: O( N*log(N) )
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。