1. 簡述
寫乙個時間複雜度盡可能低的程式,求乙個一維陣列中最長遞增子串行的長度。
例如在序列1,-1,2,-3,4,-5,6,-7中,其最長的遞增子串行的長度為4(如1,2,4,6)。
2. 思路
這個題目與前面求一維陣列中子陣列之和最大值有點像,不過區別還是很明顯,比如:子陣列是陣列中一串連續相鄰的數字,而子串行不一定是相鄰的,因此要得到[0-k]的子陣列最大和,只要分析[0-(k-1)]的子陣列最大和即可,而考慮[0-k]的子串行的最長長度,就不能只分析[0-(k-1)]中子序列的最長長度。另外乙個區別就是,子陣列的和可以擴充套件到二維陣列的情況,但是遞增子串行就不好擴充套件了,最多也就擴充套件成楊氏三角吧。
方法一:我們計算每個可能的子串行,判斷其是否為遞增的,然後選取其中最大的乙個。可能的子串行有2^n個,因此複雜度是o(2^n)。
方法二:由於我們要判斷乙個元素能否與已有的乙個子串行構成乙個更長的子串行,只有比較這個元素與這個子串行的最後乙個元素即可,那麼實際上對於[0-(i-1)]內的2^i個子序列,實際上我們只需要記錄以包含每個元素且以該元素結尾的最長子序列長度即可。即定義maxlen[i],表示a[0]-a[i]範圍內,且包含a[i]的最長子序列長度。這樣2^i個子序列用i個子序列就能夠代表了。
遞推公式為:maxlen[0]=1,maxlen[i]=max,k=0,1,2,...,i-1。
最後max,i=0,1,2,...,n-1,即為所求。
這種方法將2^n中子序列用n個子序列來代表(根據子串行構成的方法,只需要判斷子串行的最後乙個元素),複雜度為o(n^2)。
方法三:方法二實際上使用通過尾部元素的方法,從關注2^n個子序列,到關注n個分別以a[i]結尾的最長子序列上。這裡換一種對映的方法,我們關注長度分別為i,且尾部元素最小的子串行上。定義:lenminvalue[i],表示長度為i的若干子串行中,尾部的最小元素值。maxlen是當前找到的子串行最大長度。
遞推公式為:maxlen=1,lenminvalue[0] = int_min(哨兵),lenminvalue[1]=a[0]。對於a[i],我們在lenminvalue[0]-lenminvalue[maxlen]這個範圍內,找到a[i]的位置。如果a[i]>lenminvalue[maxlen],這說明要更新最大長度了,maxlen++,lenminvalue[maxlen]=a[i];如果lenminvalue[j]3. **
方法二和方法三的**,其中為了簡單實現,方法三沒有加二分搜尋。
#include結果輸出為:using
namespace std;
int find_max_len_method2(const
int *a, int n) }}
cout << "
max_len
"<< endl;
for(int i=0; i"
";cout << endl;
int result = 0;
for(int i=0; iresult ? max_len[i]:result;
delete max_len;
return result;
}int find_max_len_method3(const
int *a, int n)
else
}cout << "
len_min_value
"<< endl;
for(int i=0; i1; i++)
cout << "
d: "
<< len_min_value[i] << "
";cout << endl;
delete len_min_value;
return max_len;
}int main() ; //
1,2,4,6
cout << "
陣列:"
<< endl;
for(int i=0; i<8; i++)
cout << a[i] << "
";cout << endl;
cout << "
陣列的最長遞增子串行長度為:
"<< find_max_len_method2(a, 8) << endl;
cout << "
陣列的最長遞增子串行長度為:
"<< find_max_len_method3(a, 8) << endl;
system("
pause
");
return
0;}
4. 參考
程式設計之美,2.16節,求陣列中最長遞增子串行
2 16 求陣列中最長遞增子串行
題目 求乙個一維陣列 n個元素 中最長遞增子串行的長度 方法一 dp題 如下 include using namespace std const int maxn 100000 const int inf 10000000 int minv maxn lis maxn array maxn int ...
2 16 求陣列中最長遞增子串行
題目 求乙個一維陣列 n個元素 中最長遞增子串行的長度 dp題 如下 include using namespace std const int maxn 100000 const int inf 10000000 int minv maxn lis maxn array maxn int n li...
最長遞增子串行 程式設計之美2 16
問題 給定乙個序列an a1,a2,an 找出最長的子串行使得對所有i j,ai 1.用動態規劃實現 求最長的子串行長度 int longestincreasesubserial int array,int length 初始化各個子串行的最大長度 int currentmax new int le...