*description:最长递增子序列
* 给定数组arr,返回其最长递增子序列。
* 例:arr=[2,1,5,3,6,4,8,9,7] 返回[1,3,4,8,9]
*****************************************************************/
#include<iostream>
#include<vector>
using namespace std;
//方法一:时间复杂度O(N^2)
//先创建一个和arr同样大小的数组tmp,tmp[i]表示从0到i内最长递增子序列长度
//则tmp[0]=1,tmp[i]等于max(tmp[j], 0<j<i且arr[j]<arr[i])
//得到tmp数组之后,遍历tmp找到最长的子序列长度longest和其下标idx
//从idx开始,arr[idx]是答案的 最后一个元素,
//idx往前遍历i,arr[i]<arr[idx]且tmp[i]==tmp[idx]-1,则i是倒数第二个,同理找到其它。
vector<int> longestSubSequence_1(const vector<int> arr)
{
vector<int> res;
if (arr.size() == 0)
return res;
vector<int> tmp(arr.size());
tmp[0] = 1;
for (int i = 1; i < arr.size(); i++)
{
int max = 0;
for (int j = 0; j < i; j++)
{
if (arr[j] < arr[i])
{
max = max > tmp[j] ? max : tmp[j];
}
}
tmp[i] = max + 1;
}
int endIdx = -1;
int longest = 0;
for (int i = 0; i < tmp.size(); i++)
{
if (tmp[i] > longest)
{
longest = tmp[i];
endIdx = i;
}
}
int last = endIdx;
res.push_back(arr[endIdx]);
for (int i = endIdx - 1; i >= 0; i--)
{
if (arr[i] < arr[last] && tmp[i] == tmp[last]-1)
{
res.push_back(arr[i]);
last = i;
}
}
reverse(res.begin(),res.end());
return res;
}
//方法2:时间复杂度O(NlogN)
//利用二分法。
vector<int> longestSubSequence_2(const vector<int> arr)
{
vector<int> res;
if (arr.size() == 0)
return res;
vector<int> tmp(arr.size());
vector<int> ends(arr.size());
int right = 0;
tmp[0] = 1;
ends[0] = arr[0];
int l = 0;
int r = 0;
int m = 0;
for (int i = 1; i < arr.size(); i++)
{
l = 0;
r = right;
while (l <= r)
{
m = (l+r)/2;
if (ends[m] < arr[i])
l = m + 1;
else
r = m - 1;
}
right = right > l ? right : l;
ends[l] = arr[i];
tmp[i] = l + 1;
}
for (int i = 0; i < tmp.size(); i++)
cout << tmp[i] << " ";
cout << endl;
int endIdx = -1;
int longest = 0;
for (int i = 0; i < tmp.size(); i++)
{
if (tmp[i] > longest)
{
longest = tmp[i];
endIdx = i;
}
}
int last = endIdx;
res.push_back(arr[endIdx]);
for (int i = endIdx - 1; i >= 0; i--)
{
if (arr[i] < arr[last] && tmp[i] == tmp[last]-1)
{
res.push_back(arr[i]);
last = i;
}
}
reverse(res.begin(),res.end());
return res;
}
int main()
{
vector<int> arr;
arr.push_back(2);
arr.push_back(1);
arr.push_back(5);
arr.push_back(3);
arr.push_back(6);
arr.push_back(4);
arr.push_back(8);
arr.push_back(9);
arr.push_back(7);
vector<int> res = longestSubSequence_2(arr);
for (int i = 0; i < res.size(); i++)
cout << res[i] << " ";
return 0;
}