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)。