O(nlogn)最长递增子序列算法,如何输出所求子序列?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了O(nlogn)最长递增子序列算法,如何输出所求子序列?相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 10 //数组元素个数
int array[N] = 12,2, 34, 4, 5, 6, 7, 8, 9, 0; //原数组
int B[N]; //在动态规划中使用的数组,用于记录中间结果,其含义三言两语说不清,请参见博文的解释
int len; //用于标示B数组中的元素个数

int LIS(int *array, int n); //计算最长递增子序列的长度,计算B数组的元素,array[]循环完一遍后,B的长度len即为所求
int BiSearch(int *b, int len, int w); //做了修改的二分搜索算法

int main()

printf("LIS: %d\n", LIS(array, N));

int i;
for(i=0; i<len; ++i)

printf("B[%d]=%d\n", i, B[i]);


system("pause");
return 0;


int LIS(int *array, int n)

len = 1;
B[0] = array[0];
int i, pos = 0;

for(i=1; i<n; ++i)

if(array[i] > B[len-1]) //如果大于B中最大的元素,则直接插入到B数组末尾

B[len] = array[i];
++len;

else

pos = BiSearch(B, len, array[i]); //二分查找需要插入的位置
B[pos] = array[i];



return len;


//修改的二分查找算法,返回数组元素需要插入的位置。
int BiSearch(int *b, int len, int w)

int left = 0, right = len - 1;
int mid;
while (left <= right)

mid = left + (right-left)/2;
if (b[mid] > w)
right = mid - 1;
else if (b[mid] < w)
left = mid + 1;
else //找到了该元素,则直接返回
return mid;

return left;//数组b中不存在该元素,则返回该元素应该插入的位置

请在上述代码的基础上进行修改,使其能输出要求的子序列。
本题中,所求子序列应该是 2 4 5 6 7 8 9

参考技术A #include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
class Solution
public:
int lengthOfLIS(vector<int>& nums)
if (nums.size() == 0) return 0;

vector<int> dp(nums.size(), INT_MAX);
vector<int> pos(nums.size(), INT_MAX);

for (int i = 0; i < nums.size(); i++)
pos[i] = lower_bound(dp.begin(), dp.end(), nums[i]) - dp.begin();
*lower_bound(dp.begin(), dp.end(), nums[i]) = nums[i];

int max_n = lower_bound(dp.begin(), dp.end(), INT_MAX) - dp.begin();

vector<int> res(max_n, -1);
int j = max_n - 1;
for (int i = nums.size() - 1; i >= 0; --i)
if (j < 0) break;
if (j == pos[i])
res[j--] = nums[i];


for (auto x : res)
cout << x << " ";
cout << endl;
return max_n;

;

int main()
Solution s;
vector<int> nums = 12,2, 34, 4, 5, 6, 7, 8, 9, 0;
cout << s.lengthOfLIS(nums) << endl;
return 0;

算法总结之 最长递增子序列

给定一个数组arr,返回arr最长递增子序列

 

要求 如果长度为N 请实现时间复杂度为O(N logN)的方法

 

动态规划解题思路:

1 生成长度为N的数组dp, dp[i]表示在以arr[i]这个数结尾的情况下,arr[0....i]中的最大递增子序列长度

2 对第一个数arr[0]来说,令dp[0]=1,接下来从左到右依次算出每个位置的数结尾情况下,最长递增子序列长度

 

以上是关于O(nlogn)最长递增子序列算法,如何输出所求子序列?的主要内容,如果未能解决你的问题,请参考以下文章

hdu 5532最长非递增子序列 时间复杂度 nlogn

(转载)最长递增子序列 O(NlogN)算法

最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现

最长递增子序列 O(NlogN)算法

最长递增子序列(LIS) 贪心+二分详解O(nlogn)

算法总结之 最长递增子序列