最長嚴格遞增子序列演算法

來源:互聯網
上載者:User

代碼來源於:http://hi.baidu.com/daoyuanlee/blog/item/f5ccff07e58f69cf7a89473b.html

O(n^2) 演算法的思想

基於動態規劃:用數組a記錄數字序列,數組b記錄各a各個首碼子序列的最長嚴格遞增子序列的長度(即b[i]記錄的是a[0]...a[i]的最長嚴格遞增子序列的長度)

顯然有b[0]=1,即a[0]的最長嚴格遞增子序列長度顯然為1

在這個情況下進行增長,a[1]如果比a[0]大,那麼b[1]就為b[0]+1=2. 否則b[1]仍然為1(即最長嚴格遞增子序列為a[0]或a[1])

繼續增長至a[0],a[1],...a[i-1]的情況,此時b中下標0至i的部分也儲存了長度由1至i-2的a的首碼子序列的最長嚴格遞增子序列的長度。

此時我們從0至i-1迭代,並維護一個max變數:

1 int max = 0;
2  for (j = 0; j < i; j ++)
3 if (max < b[j] && a[j] < a[i]) max = b[j];
4 b[i] = max + 1;

迭代過程中維護一變數max,迭代中,當滿足以下2條件時更新max:

1. max < b[j]

2. a[j] < a[i]

使得max取到的是b[0]...b[i-1]中的最大值(假設為b[x]),即a[0]...a[i-1]的最長嚴格遞增子序列的長度;且有a[x]<a[i],即下一個增長到尾部的元素可以為增加當前最長嚴格遞增子序列的長度。

因此a[0]...a[i]的最長嚴格遞增子序列的長度為max+1.

增長持續至整個序列都被加入後,只需要遍曆b,取出其中最大的值,即為a的最長嚴格遞增子序列的長度。

O(n*logn)演算法

#include <iostream>

using namespace std;

const int MAX = 100;
int b[MAX];

int bs(int x,int k)
{
if(x < b[1]) return 1;
int left = 1, right = k, mid;
while(left < right-1)
{
mid = (left+right)/2;
if(b[mid] <= x) left = mid;
else right = mid;
}
return right;
}

int LIS(int n, int a[])
{
int k = 1;
b[1] = a[0];
for(int i = 1; i < n; ++i)
{
if(a[i] > b[k]) b[++k] = a[i];
else if(a[i] != b[k]) b[bs(a[i], k)] = a[i];
}
return k;
}

int main()
{
int n, i, a[MAX];
while(scanf("%d", &n) == 1)
{
for(i = 0; i < n; ++i) scanf("%d", &a[i]);
printf("%d\n", LIS(n, a));
}
return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.