《程式設計之美》上有一道關於在長度為n的陣列中找到n-1個元素乘積最大的題目,不過這並不是本文要討論的。
本文討論的是另一種情況,給定乙個長度為n的浮點陣列,找乙個長度任意的子陣列(子陣列的元素在原陣列中是連續存放的),這個子陣列的乘積最大。
通常,找乙個滿足指定條件子陣列都會使用動態規劃。遞迴縮小問題規模的同時,保持問題的數目不會指數增長。不過,本文的這個問題中,情況稍複雜
一些,由於陣列元素可能為正,為負,為0,絕對值可能大於1,也可能小於1。要使用動態規劃,需要合理設計遞迴邏輯和儲存的臨時資料。
定義p(m)從位置m開始,包含第m個元素的最大子陣列乘積,那麼我們這個問題的解就是: maxp(n) = max 。
而p(m)我們希望從p(m+1)計算出來,由於陣列中元素可能為正,也可能為負,不妨再定義:q(m)為從位置m開始,包含第m個元素的最小陣列乘積(這個乘積必須為非正數)。
那麼,p(m) = p(m+1)*a[m] , p(m+1)>=1且a[m]>0
0, a[m]=0
a[m], p(m+1)<1且a[m]>0
q(m+1)*a[m], a[m]<0
q(m) = q(m+1)*a[m], a[m]>0
0, a[m]=0
a[m], p(m+1)<1且a[m]<0
a[m]*p(m+1) p(m+1)>=1且a[m]<0
p(n)和q(n)作為初始值可以很容易知道。因此整個問題只需要o(n)的時間複雜度以及o(1)的空間複雜度。我寫的**如下,如有錯誤歡迎指正。
/* author [email protected]
* date june 29, 2013
*/#includeusing namespace std;
float lastmaxpn=-1.;
int lastmaxpb=-1;
int lastmaxpe=-1;
float maxpn=-1.;
int maxpb=-1;
int maxpe=-1;
float lastminnn=1.;
int lastminnb=-1;
int lastminne=-1;
float minnn=1.;
int minnb=-1;
int minne=-1;
int main()
n = lennums - 1;
if (nums[n] >= 0) else
n --;
while (n>=0) else else if (nums[n]>lastmaxpn)
}//update lastminnn if possible:
if (lastminnn <= 0)
} else if (nums[n] == 0) else
if (lastminnn > nums[n])
if (temp <=0)
}} //update max positive number and min negative number:
if (lastmaxpn > maxpn && (lastmaxpe-lastmaxpb)>(maxpe-maxpb))
if (lastminnn < minnn && (lastminne-lastminnb)>(minne-minnb))
n --;
} cout<
子陣列最大乘積
給定乙個double型別的陣列arr,其中的元素可正可負可0,返回子陣列累乘的最大乘積。例如arr 2.5,4,0,3,0.5,8,1 子陣列 3,0.5,8 累乘可以獲得最大的乘積12,所以返回12。解析 此題可以運用動態規劃解決 設f i 表示以i為結尾的最大值,g i 表示以i結尾的最小值,那...
子陣列最大乘積
給定乙個double型別的陣列arr,其中的元素可正可負可0,返回子陣列累乘的最大乘積。例如arr 2.5,4,0,3,0.5,8,1 子陣列 3,0.5,8 累乘可以獲得最大的乘積12,所以返回12。分析 設f i 表示以i為結尾的最大值,g i 表示以i結尾的最小值,那麼 f i 1 的最大值與...
最大乘積子陣列
問題 given an integer arraynums,find the contiguous subarray within an array containing at least one number which has the largest product.思路 看了這篇文章後突然明白...