一道好題目,把最長遞增子序列擴展到二維,但是這道題和最長遞增子序列是有區別的,它不要求是序列,只是在數組中找到一組最長的組合,不要求順序在初始中相同。
這是個二維的最長遞增子序列,由於沒有順序限制,所以我們把第一維進行排序,然後對第二維進行動態規劃
接下來就和最長遞增子序列的思路一樣:
效率是O(n^2)的算法,
struct Node
{
int x;
int y;
Node(){}
Node(int x,int y)
{
this->x = x;
this->y = y;
}
}a[100005];
int dp[100005];
int compare1(Node a,Node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int compare2(Node a,Node b)
{
if(a.x<b.x && a.y<b.y)
return 1;
return 0;
}
int pos;
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
pos=0;
for(int i=0;i<envelopes.size();i++)
{
a[pos++] = Node(envelopes[i][0],envelopes[i][1]);
}
sort(a,a+pos,compare1);
int res=0;
for(int i=0;i<pos;i++)
{
dp[i]=1;
for(int j=i-1;j>=0;j--)
{
if(compare2(a[j],a[i]))
{
dp[i]=max(dp[i],dp[j]+1);
}
}
res = max(res,dp[i]);
}
return res;
}
};
最長遞增序列,還有一種O(nlogn)的解法,這道題目也有同樣的解法。
但是這種解法裏給第一維排序的時候,第二維也要順道排一下,在第一維相同的情況,第二維排倒序,然後再去動態規劃,
這是因爲,根據O(nlogn)的解法,我們需要維護一個第二維的遞增數組,在第一維相同的而情況,第二維越小越小,在不斷往遞增數組裏插入的時候,很明顯第二維倒序會非常符合題目要求,並且減少很多不必要的判斷
struct Node
{
int x;
int y;
Node(){}
Node(int x,int y)
{
this->x = x;
this->y = y;
}
}a[100005];
int dp[100005];
int compare(Node a,Node b)
{
if(a.x==b.x)
return a.y>b.y;
return a.x<b.x;
}
int pos;
int len;
int binarySearch(int x)
{
int l=0;
int r=len-1;
while(l<=r)
{
int mid = (l+r)/2;
if(x > dp[mid])
{
l = mid+1;
}
else
{
r = mid-1;
}
}
return l;
}
int last;
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
pos=0;
for(int i=0;i<envelopes.size();i++)
{
a[pos++] = Node(envelopes[i][0],envelopes[i][1]);
}
sort(a,a+pos,compare);
return fun();
}
int fun()
{
len = 0;
for(int i=0;i<pos;i++)
{
int index = binarySearch(a[i].y);
dp[index] = a[i].y;
if(index==len)
len++;
}
return len;
}
};