面試經常出現問題:
最長遞增子串行問題是乙個很基本、較常見的小問題,但這個問題的求解方法卻並不那麼顯而易見,需要較深入的思考和較好的演算法素養才能得出良好的演算法。由於這個問題能運用學過的基本的演算法分析和設計的方法與思想,能夠鍛鍊設計較複雜演算法的思維,我對這個問題進行了較深入的分析思考,得出了幾種複雜度不同演算法,並給出了分析和證明。 一,
最長遞增子串行問題的描述
設l=<
a1,a2,…,an
>是n個不同的實數的序列,l的遞增子串行是這樣乙個子串行lin=<
ak1,ak2,…,akm
>
,其中k1
2<…m
且ak1
k2<…km
。求最大的m值。
二,第一種演算法:轉化為lcs問題求解
設序列x=<
b1,b2,…,bn
>是對序列l=<
a1,a2,…,an
>按遞增排好序的序列。那麼顯然x與l的最長公共子串行即為l的最長遞增子串行。這樣就把求最長遞增子串行的問題轉化為求最長公共子串行問題lcs了。
最長公共子串行問題用動態規劃的演算法可解。設li=<
a1,a2,…,ai
>,xj=<
b1,b2,…,bj
>,它們分別為l和x的子串行。令c[i,j]為li與xj的最長公共子串行的長度。
這可以用時間複雜度為o(
n2)的演算法求解,由於這個演算法上課時講過,所以具體**在此略去。求最長遞增子串行的演算法時間複雜度由排序所用的o(nlogn)的時間加上求lcs的o(
n2)的時間,演算法的最壞時間複雜度為o(nlogn)+o(
n2)=o(
n2)。 三,
第二種演算法:動態規劃法
設f(i)表示l中以
ai為末元素的最長遞增子串行的長度。則有如下的遞推方程:
這個遞推方程的意思是,在求以
ai為末元素的最長遞增子串行時,找到所有序號在l前面且小於
ai的元素
aj,即jaji
。如果這樣的元素存在,那麼對所有
aj,都有乙個以
aj為末元素的最長遞增子串行的長度f(j),把其中最大的f(j)選出來,那麼f(i)就等於最大的f(j)加上1,即以ai
為末元素的最長遞增子串行,等於以使f(j)最大的那個
aj為末元素的遞增子串行最末再加上
ai;如果這樣的元素不存在,那麼
ai自身構成乙個長度為1的以
ai為末元素的遞增子串行。
//動態規劃之最長遞增子串行
#include #include #include #include using namespace std;
int longestincsub(vector& vec,int length)
} int max = 0;
for (int i = 0; i < len; i++)
return max;
}//整數處理
int lcs_length_int(vector& vec1, vector& vec2, int c[100], int b[100])
else if (c[i - 1][j] >= c[i][j - 1])
else
/*cout << "計算最優值效果圖如下所示:" << endl;
for (int i = 0; i <= m; i++)
cout << endl;
}*/return c[m][n];
}int main();
int length[100] = ;
cout << longestincsub(vec1,length) << endl;
int c[100][100] = ;
int b[100][100] = ;
vectorvec2(vec1.begin(), vec1.end());
sort(vec2.begin(), vec2.end());
cout << lcs_length_int(vec1, vec2, c, b) << endl;
system("pause");
return 0;
}
使用二分查詢進行優化
/* *問題:求陣列中最長遞增子串行
*寫乙個時間複雜度盡可能低的程式,求乙個一維陣列(n個元素)中的最長遞增子串行的長度。
*例如:在序列1,-1,2,-3,4,-5,6,-7中,其最長的遞增子串行為1,2,4,6,最長遞增子串行
*的長度為4。
*求解思路:使用動態規劃+二分查詢演算法 時間複雜度o(nlog(n))
*/
#include #include using namespace std;
int lis(int *array,int len)
lis[left] = array[i];//插入
if(left > max)
} delete lis;
return max;
}
int main(int args,char **argv)
; int len = sizeof(array)/sizeof(int);
int res = lis(array,len);
cout<
動態規劃之最長遞增子串行
基本歸納法 對於ai 1,只要考察其前乙個狀態ai即可完成整個推理過程,它的特點是只要ai確定,則計算ai 1便不需要考察前序狀態a0.ai 1,我們將這一模型稱之為馬爾科夫模型 高階歸納法 相應的,對於ai 1,考察前i個狀態集才可完成整個推理過程,往往稱之為高階馬爾科夫模型 在計算機演算法中,高...
動態規劃之最長遞增子串行
1 問題描述 給定乙個序列arr,假設全是整數,給出最長的乙個遞增子串行,比如輸入arr 2,1,5,3,6,4,8,9,7 輸出 1,3,4,8,9 4 下面是 include includeusing namespace std int main 首先計算出以第i個位置結尾的最長遞增子串行的大小...
動態規劃之最長遞增子串行LIS
子串行 乙個序列 s 任意刪除若干項,剩餘的序列叫做s的乙個子串行。也可以認為是從序列s按原順序保留任意若干項得到的序列。現在我們要求解乙個陣列裡最長遞增子串行的長度。在此我提出兩種方法,並且附上 解決方法 1 利用動態規劃求解兩個陣列的最長哦公共子串行來求解這種題目,但只適用於求解最長遞增子串行的...