題目:
輸入乙個整形陣列,陣列裡有正數也有負數。
陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。
求所有子陣列的和的最大值。要求時間複雜度為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,因此輸...