面試題31 連續子陣列的最大和

2022-03-06 16:29:22 字數 2678 閱讀 9914

題目:輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間負責度為o(n)。
看到這個題目,我們首先想到的是求出這個整型陣列所有連續子陣列的和,長度為n的陣列一共有 n(n+2)/2個子陣列,因此要求出這些連續子陣列的和最快也需要o(n^2)的時間複雜度。但是題目要求的o(n)的時間複雜度,因此上述思路不能解決問題。

看到o(n)時間複雜度,我們就應該能夠想到我們只能對整個陣列進行一次掃瞄,在掃瞄過程中求出最大連續子串行和以及子串行的起點和終點位置。假如輸入陣列為,我們嘗試從頭到尾累加其中的正數,初始化和為0,第一步加上1,此時和為1,第二步加上-2,此時和為-1,第三步加上3,此時我們發現-1+3=2,最大和2反而比3乙個單獨的整數小,這是因為3加上了乙個負數,發現這個規律以後我們就重新作出累加條件:如果當前和為負數,那麼就放棄前面的累加和,從陣列中的下乙個數再開始計數。

**例項:

view code

#include#include

using

namespace

std;

//求最大連續子串行和

int findgreatestsumofsubarray(int arry,int

len)

else

currsum+=arry[i];//

如果當前最大和不為負數則加上當前數

if(currsum>greatestsum)//

如果當前最大和大於全域性最大和,則修改全域性最大和

}cout

<

最大子串行位置:

"return

greatestsum;

}void

main()

;

int len=sizeof(arry)/sizeof(int

);

//cout

cout

<

最大子串行和:

"system(

"pause");

}

經過@yu's 技術生涯 測試,發現我上面的**確實存在問題,現在做了如下修改:

1.新增了乙個遍歷用於儲存遍歷陣列中發現的最大和的起始,原來的start和end只用於儲存真是的開始於結尾。

2.當currsum<0的時候,我們只讓p值為最大和子陣列的開始

3.在最後判斷currsum>greatestsum的時候,只有當currsum>greatestsum成立,才讓start=p,否則就表明以p開頭的子陣列最大和不是最大的。

示例**如下:

view code

#include#include

using

namespace

std;

//求最大連續子串行和

int findgreatestsumofsubarray(int arry,int

len)

else

currsum+=arry[i];//

如果當前最大和不為負數則加上當前數

if(currsum>greatestsum)//

如果當前最大和大於全域性最大和,則修改全域性最大和

}cout

<

最大子串行位置:

"return

greatestsum;

}void

main()

;int arry=;

int len=sizeof(arry)/sizeof(int

);

//cout

cout

<

最大子串行和:

"system(

"pause");

}

如果用函式f(i)表示以第i個數字結尾的子陣列的最大和,那麼我們需要求出max(f[0...n])。我們可以給出如下遞迴公式求f(i)

這個公式的意義:

當以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)小於0時,如果把這個負數和第i個數相加,得到的結果反而不第i個數本身還要小,所以這種情況下最大子陣列和是第i個數本身。

如果以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)大於0,與第i個數累加就得到了以第i個數結尾的子陣列中所有數字的和。

view code

//

使用動態規劃求最大連續子陣列和

int findgreatestsumofsubarray2(int arry,int len,int

c)

else

c[i]=arry[i]+c[i-1

];

if(c[i]>maxgreatsum)

}//輸出c[i]

for(int i=0;i)

cout

cout

<

cout

<

最大子串行位置:

"return

maxgreatsum;

}

其實上述兩種方法的實現方式非常相似,只是解體思路不同而已。通常我們會使用遞迴的方式分析動態規劃的問題,但是最終都會基於迴圈去寫**。在動態規劃方法中建立了乙個陣列c用於儲存中間結果,而第一種方法中只需要乙個臨時變數currsum.

面試題31 連續子陣列的最大和

題目 輸入乙個整形陣列,陣列裡有正數也有負數,陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o n 例如,輸入陣列 1,2,3,10,4,7,2,5 和最大的子陣列微3,10,4,7,2,因此輸出該子陣列的和18 思路 1,分析陣列規律 初始化和0,第一哥數字1...

面試題31 連續子陣列的最大和

面試題31 連續子陣列的最大和 hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量...

面試題31連續子陣列的最大和

題目 輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間負責度為o n 看到這個題目,我們首先想到的是求出這個整型陣列所有連續子陣列的和,長度為n的陣列一共有 n n 2 2個子陣列,因此要求出這些連續子陣列的和最快也需要o n 2 ...