典型的輸入能幫助我們測試演算法的邏輯。
在寫具體演算法前列出各種可能輸入,可以幫助明確題目的要求。
最直接的方法:
記 sum[i, …, j] 為 陣列a中第i個元素到第j個元素的和(其中 0≤i
≤j
<
n0\leq i\leq j< n
0≤i≤
j<
n),遍歷所有可能的sum[i, …, j] ,那麼時間複雜度為o(n
3)
o(n^3)
o(n3):
int
maxsum
(int
* a,
int n)
if(sum>maximum)
maximum=sum;}}
return maximum;
}
改進的直接法:
注意到 sum[i, …, j]= sum[i, …, j-1]+a[j],則可以將演算法中的最後乙個for迴圈省略,避免重複計算,從而使得演算法得以改進,改進後的演算法複雜度為o(n
2)
o(n^2)
o(n2):
int
maxsum
(int
* a,
int n)
}return maximum;
}
分治演算法:
把問題分解為兩個規模減半的子問題,再採用一次遍歷演算法。
總的時間複雜度為t(n
)=o(
n∗lo
g2n)
t(n)=o(n*log_2n)
t(n)=o
(n∗l
og2
n)問題規模減半的相同子問題,可以通過遞迴求得。
跨越中間元素的處理方法:
兩個子陣列分別為 (a[0],…,a[n/2-1]) 和 (a[n/2],…,a[n-1])
跨越中間元素的情況只要找到以a[n/2-1]結尾的最大陣列和s1=
sum(
a[i]
,...
,a[n
/2−1
])(0
≤i
−1 )s_1=sum(a[i],...,a[n/2-1]) (0\leq i < \frac-1) s1=su m(a[ i],. ..,a [n/2 −1]) (0≤i <2n −1) 與以 a[n/2] 開始的最大陣列和s2= sum( a[n/ 2],. ..,a [j]) (n2≤ j s_2=sum(a[n/2],...,a[j]) (\frac \leq j < n) s2=su m(a[ n/2] ,... ,a[j ])(2 n≤j 。那麼這種情況下的最大值為s1+ s2=a [i]+ ...+ a[n/ 2−1] +a[n /2]+ ...+ a[j] s_1+s_2=a[i]+...+a[n/2-1]+a[n/2]+...+a[j] s1+s2 =a[ i]+. ..+a [n/2 −1]+ a[n/ 2]+. ..+a [j],只需對原陣列進行一次遍歷即可。 動態規劃: 選與不選a[0] 考慮陣列的第乙個元素a[0],以及和最大的一段陣列 (a[i],…,a[j]) 跟 a[0] 之間的關係,有以下幾種情況: 當 0=i=j 時,元素 a[0] 本身構成和最大的一段; 當 0=i當 0 m ax max\ max max( int x, int y) //返回x,y兩者中較大的值 intmaxsum (int * a, int n) return all[0] ;//遍歷完陣列,all[0]中存放著結果 }上述方法的時間複雜度已經降到o(n )了 。o(n)了。 o(n)了。 思考:上述**額外申請了兩個陣列all,start,能否在空間方面節省一些? 進一步改進只需要o(1 )o(1) o(1) 的空間int
int
max(
int x,
int y)
//返回x,y兩者中較大的值
intmaxsum
(int
* a,
int n)
return nall;
求子陣列和的最大值
題目要求 輸入乙個一維整形陣列,陣列裡有正數也有負數。一維陣列首尾相接,像個一條首尾相接帶子一樣。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。程式設計思路 1 首先建立乙個一維陣列a,進行資料儲存。2 定義變數,n用於求和,m為和最大值 3 開始for迴...
求子陣列的和的最大值
一 題目 輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o n 例子說明 例如輸入的陣列為,和最大的子陣列為 3,10,4,7,2 因此輸出為該子陣列的和18 二 解題思路 舉例分析陣列的規律。我們試著從頭到尾逐個累加示例...
erlang 求子陣列和的最大值
前段時間修改為簡單方法 module son export son 1 son a son a,0,0 son max,sum max son head list max,sum new sum head sum,new max case new sum max of true new sum ma...