[编程题] 最长递增子序列
对于一个数字序列,请设计一个复杂度为O(nlogn)的算法,返回该序列的最长上升子序列的长度,这里的子序列定义为这样一个序列U1,U2...,其中Ui < Ui+1,且A[Ui] < A[Ui+1]。
给定一个数字序列A及序列的长度n,请返回最长上升子序列的长度。
测试样例:
[2,1,4,3,1,5,6],7
返回:4
// 最长递增子序列.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
using namespace::std;
unsigned int liss(const int array[], size_t length, int result[]) {
unsigned int i, j, k, max;
vector<int> liss;
vector<int> pre;
for (int i = 0; i < length; ++i) {
liss.push_back(1);
pre.push_back(i);
}
for (i = 1, max = 1, k = 0; i < length; ++i){
for (j = 0; j < i; ++j) {
if (array[j] < array[i] && liss[j] + 1 > liss[i]){
liss[i] = liss[j] + 1;
pre[i] = j;
if (max < liss[i]){
max = liss[i];
k = i;
}
}
}
}
i = max - 1;
while (pre[k] != k){
result[i--] = array[k];
k = pre[k];
}
result[i] = array[k];
return max;
}
int _tmain(int argc, _TCHAR* argv[])
{
int array[] = { 2, 1, 4, 3, 1, 5, 6 };
int result[7];
int test = liss(array, 7, result);
return 0;
}
第二次做:
class AscentSequence {
public:
int findLongest(vector<int> vec, int n) {
// write code here
if ( vec.empty() == true ) return -1 ;
vector<int> liss( vec.size(), 1 ) ; // 用于记录当前各元素作为最大元素的最长递增序列长度
int max = 0 ;
for ( int i = 0; i < vec.size(); ++ i ) {
// 找到以 vec[i] 为最末元素的最长递增子序列
for ( int j = 0; j < i; ++ j ) {
// 如果要求非递减子序列,只需将 vec[j] < vec[i] 改写为 vec[j] <= vec[i]
// 如果要求递减子序列,只需改为 vec[j] > vec[i]
if ( vec[j] < vec[i] && liss[j] + 1 > liss[i] ) {
liss[i] = liss[j] + 1 ;
if ( max < liss[i] ) max = liss[i] ; // 得到当前最长递增子序列的长度
}
}
}
return max ;
}
};