最大子序列和演算法分析,子序列演算法分析_PHP教程

來源:互聯網
上載者:User

最大子序列和演算法分析,子序列演算法分析


問題描述:給定n個整數序列{a1,a2,...,an},求函數f(i,j)=max{0,Σak}(k:連續的從i取到j);

問題即為求已連續子列和的最大值,若果最大值為負數則取0,比如8個數序列{-1,2,-3,4,-2,5,-8,3},那摩最大子序列和為4+(-2)+5=7.

這個問題有四種不同複雜度的演算法,演算法1到四的時間複雜度是O(n3),O(n2),O(nlogn),O(n);

演算法一:

最直接的方法是窮舉法,列出所有的情況,我們可以設定子序列的左端i和右端j,再利用一層計算出a[i]到a[j]的和.

//最大子列和窮舉法
#include
using namespace std;
int Find_Maxsun(int*a, int n);
int main(){
int n, i;
int a[100];
cin >> n;
cout << "Pleace Input The " << n << "Number:" << endl;
for (i = 0; i < n; i++)
cin >> a[i];
cout<return 0;
}
int Find_Maxsun(int*a, int n){
int MaxSun = 0, i, j, k;
int NowSum;
for (i = 0; i < n; i++) /*子序列左端*/
for (j = 0; j < n; j++){ /*子序列右端*/
NowSum = 0;
for (k = i; k <= j; k++)
NowSum += a[k]; /*從a[i]到a[j]的子序列*/
if (NowSum>MaxSun)
MaxSun = NowSum; /*更新結果*/
}
return MaxSun;
}

很顯然,暴力法使用啦3重for迴圈,演算法時間複雜度為O(n3),這當然也是一個最笨的演算法,但資料難非常龐大時候,哪怕是要算到死的節奏,我們可以清楚看到第三層for迴圈,

j每加一次,子列和都要重頭算一次,那我們為何不去利用j-1的結果呢?也就是說我們將j-1的結果儲存下來,在計算j步的結果時候,只需要在j-1步的基礎上再加上a[j],就可以啦,於是有啦演算法二。

演算法二:

#include
using namespace std;
int Find_Maxsun2(int*a, int n);
int main(){
int n, i;
int a[100];
cin >> n;
cout << "Pleace Input The " << n << " Number:" << endl;
for (i = 0; i < n; i++)
cin >> a[i];
cout << Find_Maxsun2(a, n) << endl;
return 0;
}
int Find_Maxsun2(int*a, int n){
int i, j, NewSum = 0, MaxSum= 0;
for (i = 0; i < n; i++){ /*為序列的左邊端點*/
NewSum = 0;
for (j = i; j < n; j++){ /*j為系列右端點*/
NewSum += a[j]; /*每一次在j-1條件下更新NewSum*/
if (NewSum>MaxSum) /*更新MaxSum*/
MaxSum = NewSum;
}
}
return MaxSum;
}

這個演算法比1聰明,演算法複雜度是O(n2),顯然還不是我們想要的複雜度。

演算法三:

演算法三使用的是分治法的思想,基本思想不言而喻先分後治,將問題分解為小問題然後在可以總和小問題來解決,我們把原序列一分為二,那麼最大子序列在左邊,在右邊,或者跨越邊界,基本思路如下:

第一步:將原序列一分為二,分成左序列和右序列。

第二步:遞迴求出子序列S左和S右。

第三部:從中分線向兩邊掃描,找出跨越中線的最大子序列和S中。

第四步:求得S=max{S左,S中,S右};

代碼實現如下:

#include
using namespace std;
int Find_MaxSum3(int*a,int low,int high);
int Max(int a,int b,int c);
int main(){
int n, i;
int a[100];
cin >> n;
cout << "Pleace Input The " << n << " Number:" << endl;
for (i = 0; i < n; i++)
cin >> a[i];
cout << Find_MaxSum3(a,0,n-1) << endl;
return 0;
}
int Find_MaxSum3(int*a,int low,int high){
int MaxSum = 0, MidSum, LeftSum, RightSum,i;
MidSum = 0;
if (low == high){ /*遞迴的終止條件*/
if (a[low] > 0)
return a[low];
else
return 0;
}
int mid = (low + high) / 2; //找到分的中點
LeftSum = Find_MaxSum3(a, low, mid); /*遞迴找到左邊序列最大和*/
RightSum = Find_MaxSum3(a, mid + 1, high); /*遞迴找到右邊序列最大子序列和*/
/*然後可以求中間跨越邊界序列的最大和*/
int NewLeft = 0,Max_BorderLeft=0, NewRight = 0,Max_BorderRight=0;
for (i = mid; i >= low; i--){ /*向左掃描找到最大和*/
NewLeft += a[i];
if (NewLeft > Max_BorderLeft)
Max_BorderLeft = NewLeft;
}
for (i = mid + 1; i <= high; i++){ /*向右掃描找到最大子序列和*/
NewRight+=a[i];
if (NewRight >= Max_BorderRight)
Max_BorderRight = NewRight;
}
MidSum = Max_BorderRight + Max_BorderLeft;
return Max(LeftSum, MidSum, RightSum); /*返回治的結果*/
}
int Max(int a, int b, int c){ /*找出3者中最大的數*/
if ( a>= b&&a >= c)
return a;
if (b >= a&&b >= c)
return b;
if (c >= b&&c>=a)
return c;
}

我們來算一算這個演算法時間複雜度:

T(1)=1;

T(n)=2T(n/2)+O(n);

=2kT(n/2k)+kO(n)=2kT(1)+kO(n)(其中n=2k)=n+nlogn=O(nlogn);

雖然這個演算法已經非常好啦,但是並不是最快的演算法。

演算法四:

演算法四叫做線上處理。意思為,每讀入一個資料就進行及時處理,得到的結果是對於當前讀入的資料都成立,即為在任何位置終止讀入,演算法都可以給出正確的解,邊讀邊解。

#include
using namespace std;
int Find_MaxSum4(int*a, int n);
int main(){
int n, i;
int a[100];
cin >> n;
cout << "Pleace Input The " << n << " Number:" << endl;
for (i = 0; i < n; i++)
cin >> a[i];
cout << Find_MaxSum4(a,n) << endl;
return 0;
}
int Find_MaxSum4(int*a, int n){
int i, NewSum = 0, MaxSum = 0;
for (i = 0; i < n; i++){
NewSum += a[i]; /*當前子序列和*/
if (MaxSum < NewSum)
MaxSum = NewSum; /*更新最大子序列和*/
if (NewSum < 0) /*小於0則拋棄*/
NewSum = 0;
}
return MaxSum;
}

這種演算法是將讀入的資料一個個掃描一遍,只有一個for迴圈,解決同一個問題演算法差別大,在於一個竅門,讓電腦記住一些關鍵的中間結果,避免重複計算。

http://www.bkjia.com/PHPjc/1044670.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1044670.htmlTechArticle最大子序列和演算法分析,子序列演算法分析 問題描述:給定n個整數序列{a1,a2,...,an},求函數f(i,j)=max{0,a k }(k:連續的從i取到j); 問題即為求已連續...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.