1.自己的解題思路是用動態規劃的思想,從後往前遍歷
定義f(x)表示以a[x]爲最小元素的最長遞增子序列的長度;則f(n-1)=1;
f(i) = 1,如果對於任意的j>i有 a[i]>=a[j];
f(i)=1+f(j),其中j滿足a[i]<a[j];,且是滿足j>i所有j中最小的一個。
實現代碼如下:
int Solute1(vector<int> &Vec)
{
int maxLength = 1;
int *tempArrayp = new int[Vec.size()]();
for(int i=Vec.size()-1 ; i>=0 ; i--){
tempArrayp[i] = 1;
for(int j=i+1 ; j<Vec.size() ; j++){
if(Vec[i] < Vec[j]){
tempArrayp[i] = tempArrayp[j] + 1;
if(tempArrayp[i] > maxLength){
maxLength = tempArrayp[i];
}
break;
}
}
}
delete []tempArrayp;
return maxLength;
}
2.書中的解法一是從前往後遍歷,定義f(n)表示以a[n]爲最大元素的最長遞增子序列的長度。
f(n+1) = max{1,f(i)+1},其中a[i]<a[n+1],對於任意的i≤n;
實現代碼如下:
int Solute2(vector<int> &Vec)
{
int maxLength = 1;
int *tempArrayp = new int[Vec.size()]();
for(int i=0 ; i<Vec.size() ; i++){
tempArrayp[i] = 1;
for(int j=i-1 ; j>=0 ; j--){
if(Vec[i]>Vec[j] && tempArrayp[i]<tempArrayp[j]+1){
tempArrayp[i] = tempArrayp[j] + 1;
if(tempArrayp[i] > maxLength){
maxLength = tempArrayp[i];
}
//break;
}
}
}
delete []tempArrayp;
return maxLength;
}
3.書中的改進算法,沒具體看實現,只是看了下思路,可能略有不同。
改進Solute2中第二個for循環,增加maxV數組,記錄滿足長度爲i的子序列的最大元素的最小值。
int Solute3(vector<int> &Vec)
{
int *tempArrayp = new int[Vec.size()]();
vector<int> maxV;
maxV.push_back(0);
for(int i=0 ; i<Vec.size() ; i++){
tempArrayp[i] = 1;
for(int j=maxV.size()-1 ; j>=0 ; j--){
if(Vec[i]>Vec[maxV[j]]){
tempArrayp[i] = tempArrayp[maxV[j]] + 1;
if(tempArrayp[i]>maxV.size()-1){
maxV.push_back(i);
}
}
}
}
delete []tempArrayp;
return maxV.size();
}
三個算法的複雜度都是O(n^2),方法一和方法三比方法二查找次數少,方法三可以進一步用二分思想改進,複雜度達到O(nlgn)。