問題描述:輸入是乙個大小為n的整型陣列,要求輸出陣列的任何連續子陣列中的最大值。例如:輸入的陣列為array[10] = ;輸出最大連續子陣列和為array[2...6]:187
演算法1:對所有滿足0<=i<=j<=n的(i,j)整數對進行迭代,對每個整數對,程式都要計算array[i...j]的總和,並檢驗該總和是否大於迄今為止的最大總和。
演算法1的偽**描述如下:
1 maxsofar = 02for(i=0;ij)
3for(j=i;jj)
4 tmepsum = 0
5for(k=i;k<=j;++k)
6 tempsum +=array[k]
7 maxsofar = max(maxsofar,tempmax)
這段**簡潔明瞭,便於理解,但是程式執行的速度很慢,時間複雜度為o(n^3)。
演算法2:對於演算法1有乙個明顯的方法可以使其執行起來快得多。使得時間複雜度控制住平方o(n^2)。
第乙個平方演算法注意到,array[i...j]的總和與前面計算出的總和(array[i...j-1])密切相關,利用這一點可以達到演算法2。
演算法2_1的偽**描述如下:
1 maxsofar = 02for(i=0;ii)
3 tempsum = 0;4
for(j=i;jj)
5 tempsum +=array[j]
6 maxsofar = max(maxsofar,tempsum)
第二個平方演算法是引入乙個陣列curarray,大小也為n,通過空間來換取時間,通過訪問外迴圈執行之前計算[0...i]各個連續字段總和。curarrary中的第i個元素包含array[0...i]中各個數的累加和,所以x[i...j]中各個數的總和可以通過計算curarray[j] -curarray[i-1]得到.
演算法2_2的偽**描述如下:
1 curarray[-1] = 02for(i=0;ii)
3 curarray[i] = curarray[i-1]+x[i]
4 maxsofar = 0
5for(i=0;ii)
6for(j=i;jj)
7 sum = curarray[j]-curarray[i-1
]8 maxsofar = max(maxsofar,sum)
演算法3:可以考慮採用法治演算法。初始問題是要處理大小為n的陣列,所以可以將其劃分為兩個子陣列a和b,然後遞迴的找出a、b中元素總和最大的子陣列分別為maxa、maxb。而最大子陣列要麼在a中,要麼在b中,要麼跨越a和b之間的邊界,我們將跨越邊界的最大子陣列記為maxc。我們通過分治演算法計算處了maxa和maxb,通過某種辦法計算處maxc。然後返回三個中的最大值就是我們所要的最大子陣列和。演算法的時間複雜度為o(nlogn)。如何計算maxc呢?通過觀察發現,maxc在a中的部分是a中包含右邊界的最大子陣列,而maxc在b中的部分是b中包含左邊界的最大子陣列。將這些綜合一起我們得到演算法3:
1int maxsum3(1
,n)2
演算法4:我們現在採用運算元組的最簡單的演算法:從陣列最左端(元素x[0])開始掃瞄,一直到最右端(元素array[n-1])為止,並記下所遇到的最大總和的子陣列。最大總和開始設為0.假設我們已經解決了array[0...i-1]的問題,那麼如何將其擴充套件為包含x[i]的問題呢?我們用類似於分治演算法的原理:前i個元素中,最大總和子陣列要麼在前i-1個元素中(將其存maxsofar中),要麼其結束位置為i(將其存入maxendinghere中)。不從頭開始計算結束位置為i的最大子陣列,而是利用結束位置為i-1的最大子陣列進行計算。這樣就得到了演算法4:
1 maxsofar = 02 maxendinghere = 0
3for(i=0;ii)
4 maxendinghere = max(maxendinghere+array[i],0
)5 maxsofar = max(maxsofar,maxendinghere)
理解這個程式的關鍵在於maxendinghere。在迴圈中第乙個賦值語句之前,maxendinghere是結束位置為i-1的最大子陣列的和,賦值語句將其修改為結束位置為i的最大子陣列的和。若加上array[i]的後的結果為正值,則該賦值語句使maxendinghere增大x[i],若加上x[i]之後結果為負值,該賦值語句將maxendinghere重新設定為0(因為結束位置為i的最大子陣列現在為空)。這個地方有些難度,需要認真思考揣摩。時間複雜度為o(n),線性演算法,效率最高。
下面針對這4個演算法寫乙個完成的程式來進行測試,程式如下:
1 。#include 2using
namespace std; //
求兩個數種最大值
3int max(const
int m,const
intn)
4 //
求三個整數中的最大值
7int max(const
int x,const
int y,const
intz)
8 //
演算法1函式實現
13int maxsum1(int *array,const
size_t len)
1426}27
return
maxsofar;
28 } //
演算法2.1的實現
29int maxsum2_1(int *array,const
size_t len)
3041}42
return
maxsofar;
43 } //
演算法2.2的實現
44int maxsum2_2(int *array,const
size_t len)
45 //
演算法3的實現
59int maxsum3(int *array,const
int begin,const
intend)
6072 tempsum = 0;73
for(int j=mid+1;j<=end;++j)
7478
return max(lmax+rmax,maxsum3(array,begin,mid),maxsum3(array,mid+1
,end));
79 } //
演算法4的實現
80int maxsum4(int *array,const
size_t len)
8189
return
maxsofar;
90 } int
main()91;
93int
choise;
94 cout<<"
1.演算法1
"<95 cout<<"
2.演算法2_1
"<96 cout<<"
1.演算法1
"<97 cout<<"
3.演算法3
"<98 cout<<"
4.演算法4
"<99 cout<<"
5.演算法2_2
"<100 cout<<"
0.退出
"<101while(1
)102
126}
127return0;
128 }
陣列的連續最大子段和
轉至 anker s blog 問題描述 輸入是乙個大小為n的整型陣列,要求輸出陣列的任何連續子陣列中的最大值。例如 輸入的陣列為array 10 輸出最大連續子陣列和為array 2.6 187 演算法1 對所有滿足0 i j n的 i,j 整數對進行迭代,對每個整數對,程式都要計算array i...
陣列的連續最大子段和
最大子段和問題描述 給定由 n 個整數 可能為負整數 組成的序列a1,a2,a3.an,求該數列中連續子段和最大!例如 當 a1,a2,a3,a4,a5 2,11,4,13,5,2 時,最大欄位和為 20 11 4 13 以下例子都是以int data 6 int n 6 演算法一 對所有滿足0 i...
陣列的連續最大子段和
問題描述 輸入是乙個大小為n的整型陣列,要求輸出陣列的任何連續子陣列中的最大值。例如 輸入的陣列為array 10 輸出最大連續子陣列和為array 2.6 187 演算法1 對所有滿足0 i j n的 i,j 整數對進行迭代,對每個整數對,程式都要計算array i.j 的總和,並檢驗該總和是否大...