求子陣列的最大和

2021-06-23 05:39:41 字數 2563 閱讀 4897

題目:

輸入乙個整形陣列,陣列裡有正數也有負數。

陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。

求所有子陣列的和的最大值。要求時間複雜度為o(n)。

例如輸入的陣列為1,-2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,

因此輸出為該子陣列的和18。

下面將逐步,從效率比較低的演算法到效率比較高的演算法,最後以時間複雜度o(n)的演算法來實現求子陣列的和的最大值。

1、 最簡單的,時間複雜度o(n*n*n)的演算法。

將所有的(i,j)對兒都遍歷一遍(i,j滿足條件:0=

maxsofar=0

for i=[0,n)

for j=[i,n)

sum=0;

fork=[i,j]

sum=sum+x[k]  //sum代表x[i]到x[j]的和

maxsofar=max(maxsofar,sum)//max函式用來返回maxsofar和sum兩者中的最大值

2、時間複雜度為o(n*n)的兩個演算法

第乙個是利用「x[i]到x[j]的和等於x[i]到x[j-1]的和加上x[j]」這一性質。**是一種的**稍作調整,偽**如下:

maxsofar=0

for i=[0,n)

sum=0

for j=[i,n)

sum=sum+x[j]

maxsofar=max(maxsofar,sum)

第二個是利用空間來換取時間的乙個演算法,它將從第乙個元素開始到第j+1(j=[0,n))元素的和都存起來(存在陣列cumarr中),這樣每次計算x[i]到x[j]的和時,只需用cumarr[j]-cumarr[i-1]即可得到。偽**如下:

cumarr[-1]=0 

for i=[0,n)

cumarr[i]=cumarr[i-1]+x[i]

for i=[0,n)

for j=[i,n)

sum=cumarr[j]-cumarr[i-1]

maxsofar=max(maxsofar,sum)

3、利用這個思想(divide-and-conquerrecipe):把解決乙個大問題分解成解決幾個子問題,然後把這幾個子問題的結果整合起來,進而解決這個大問題。 

利用遞迴演算法。利用下面思路:x[l]到x[u]的最大子陣列是下面三種情況之一(假設m=(l+u)/2):1、x[l]到x[u]的最大子陣列完全出現在x[l]到x[m]之間。2、x[l]到x[u]的最大子陣列完全出現在x[m]到x[u]之間。3、x[l]到x[u]之間的最大子陣列是x[a]到x[b],其中a

intmaxsum(l,u) 

//返回子陣列和最大值的函式maxsum

if(l>u)

return0

if(l==u)

return x[l]

m=(l+u)/2

lmax=sum=0

for(i=m;i>=l;i++)

sum=sum+x[i]

lmax=max(lmax,sum)

rmax=sum=0 

for(i=m+1;i<=u;i++)

sum=sum+x[i]

rmax=max(rmax,sum)

return max(lmax+rmax,maxsum(l,m),maxsum(m+1,u));

時間複雜度:t(n)=2t(n/2)+o(n) 

可以推得:t(n)=o(nlogn)

4、時間複雜度o(n),最優的一種演算法。

最簡單的操作在陣列上的演算法是:從總左邊(x[0])開始遍歷整個陣列,一直到最右邊結束(x[n-1]),在這個過程中記錄到目前為止最大的子陣列和maxsofar。maxsofar初始化成0。假如我們已經找到x[0]到x[n-1]之間的最大子陣列和,那麼x[0]到x[i]之間的最大子陣列和是怎樣的呢?要麼「還是x[0]到x[i-1]之間的最大子陣列和」,要麼是「從x[i]開始,往前幾個連續的數的最大值」。

在求從x[i]開始,往前幾個連續的數的最大值時,用到如下性質:從x[i]開始往前幾個連續的數的最大值maxending_i等於(maxending_i-1)+x[i]和0兩者之中的最大值,即

maxending_i=max((manending_i-1)+x[i],0)

下面是這個演算法的偽**:

maxsofar=0

maxendinghere=0

for i=[0,n)

maxendinghere=max(maxendinghere+x[i],0)

maxsofar=max(maxendinghere,maxsofar)

下面是演算法4的c語言**,可以參考:

#include

#define max(a,b)((a)>(b)?(a):(b)) 

//定義計算a,b兩者中最大值的巨集

int maxsum(int arr,int num)

return maxsofar;

}int main()

;int max=maxsum(a,8);

printf("%d\n",max);

return 0;

}**:

求子陣列最大和

題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此輸出為該子陣列的和18。因為是o n 的複雜度,...

求子陣列的最大和

題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 本題最初為2005年浙江大學計算機系的考研題的最後一道程式設計題,在2006年裡包括google在內的很多知名公司都把本題當作面試題。由於本...

求子陣列的最大和

陣列 一 題目 感謝 提供的題目 求子陣列的最大和 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此輸...