[C++]最長遞增子序列的求法之一(學習)
阿新 • • 發佈:2019-02-16
測試程式碼
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
/*
array: int陣列
length: 陣列長度
pre: array同等長度的int陣列 記錄第i個結點的前驅
nIndex: 最大長度所在的下標
*/
int LIS(const int*array, int length, int* pre, int &nIndex) {
int * longest = new int[length];
//初始化資料
for (int i = 0; i < length; i++) {
//記錄第i的結點最長的長度 初始化為1
longest[i] = 1;
//記錄當前長度結點的前驅 初始化為-1
pre[i] = -1;
}
//記錄最長的長度 初始化為1
int nLis = 1;
for (int i = 0; i < length; i++) {
for (int j = 0; j < i; j++) {
if (array[j] <= array[i]) {
//如果遞增 並且通過第j個結點可以達到更長則更新並記錄前驅
if (longest[i] < longest[j] + 1) {
longest[i] = longest[j] + 1;
pre[i] = j;
}
}
}
//統計最大的值及位置
if (nLis < longest[i]) {
nLis = longest[i];
nIndex = i;
}
}
delete [] longest;
return nLis;
}
//獲取最大長度的序列 主要通過前驅查詢
void GetLis(const int* array, const int* pre,vector<int>&lis,int nIndex) {
while (nIndex >= 0)
{
lis.push_back(array[nIndex]);
nIndex = pre[nIndex];
}
//陣列翻轉
reverse(lis.begin(), lis.end());
}
//輸出序列
void Print(int *head,int size) {
for (int i = 0; i < size; i++)
cout << head[i] << " ";
cout << endl;
}
int main()
{
int array[] = {23,56,43,12,78,4,9,10,68,42};
int size = sizeof(array) / sizeof(int);
int *pre = new int[size];
int nIndex;
int max = LIS(array, size, pre, nIndex);
vector<int> lis;
GetLis(array, pre, lis, nIndex);
Print(array, size);
cout << "最大長度: " << max << endl;
Print(&lis.front(),lis.size());
delete[] pre;
system("pause");
return 0;
}