陣列中最大和子陣列

2021-06-25 19:59:37 字數 2070 閱讀 9297

題目:

輸入乙個整型陣列,資料元素有正數也有負數,求元素組合成連續子陣列之和最大的子陣列,要求時間複雜度為o(n)。

例如:

輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,最大和的連續子陣列為3, 10, -4, 7, 2,其最大和為18。

背景:

本題最初為2023年浙江大學計算機系考研題的最後一道程式設計題,在2023年裡包括google在內的很多知名公司都把本題當作面試題。

由於本題在網路中廣為流傳,本題也順利成為2023年程式設計師面試題中經典中的經典。

分析:

如果不考慮時間複雜度,我們可以列舉出所有子陣列並求出他們的和。不過非常遺憾的是,由於長度為n的陣列有o(n2)個子陣列(即:n + n-1 + ... + 1=n(n+1)/2);而且求乙個長度為n的陣列的和的時間複雜度為o(n)。因此這種思路的時間是o(n3)。

很容易理解,當我們加上乙個正數時,和會增加;當我們加上乙個負數時,和會減少。

如果當前得到的和是個負數,那麼這個和在接下來的累加中應該拋棄並重新清零,不然的話這個負數將會減少接下來的和。基於這樣的思路,我們可以寫出如下**。

[cpp]view plain

copy

print?

void

maxsum(

intarray, unsigned 

intlen)  

intcursum = 0, maxsum = 0;  

inti = 0;  

for(i=0; i

cursum += array[i];     // 累加

if(cursum 

if(cursum > maxsum)  

}  if

(maxsum == 0)  

}  }  

printf("maxsum: %d"

, maxsum);  

}  

測試陣列:

[cpp]view plain

copy

print?

intarray = ;     

// 3, 10, -4, 7, 2 = 18

執行結果:

**改進:

有時,需要輸出最大和的子陣列及其開始、結束下標,**如下:

[cpp]view plain

copy

print?

void

maxsum(

intarray, unsigned 

intlen)  

intcursum = 0, maxsum = 0;  

intindex_start = 0, index_end = 0;     

// 初始化子陣列最大和下標

inti = 0;  

for(i=0; i

cursum += array[i];     // 累加

if(cursum 

if(cursum > maxsum)  

}  if

(maxsum == 0)  

}  }  

// 輸出最大和的子陣列及其開始、結束下標

printf("index_start: %d\nindex_end: %d\n"

, index_start, index_end);  

for(i=index_start; i<=index_end; i++)  

printf("\n\nmaxsum: %d"

, maxsum);  

}  

測試陣列:

[cpp]view plain

copy

print?

intarray = ;     

// 3, 10, -4, 7, 2 = 18

執行結果:

陣列中最大和的子陣列

題目 輸入乙個整型陣列,資料元素有正數也有負數,求元素組合成連續子陣列之和最大的子陣列,要求時間複雜度為o n 例如 輸入的陣列為1,2,3,10,4,7,2,5,最大和的連續子陣列為3,10,4,7,2,其最大和為18。背景 本題最初為2005年浙江大學計算機系考研題的最後一道程式設計題,在200...

陣列中最大和的子陣列

題目 輸入乙個整型陣列,資料元素有正數也有負數,求元素組合成連續子陣列之和最大的子陣列,要求時間複雜度為o n 例如 輸入的陣列為1,2,3,10,4,7,2,5,最大和的連續子陣列為3,10,4,7,2,其最大和為18。背景 本題最初為2005年浙江大學計算機系考研題的最後一道程式設計題,在200...

求連續子陣列中最大和

思路 動態規劃 遍歷陣列,遇到負的和則放棄之前的結果,重新積累,這期間保留最大值 用max記錄最終返回的最大和,用curmax記錄累加值 對於數值中乙個數arr i 若其左邊的累加和非負,那麼加上arr i 判斷此時的curmax是否大於max,若大於此時的max,則用max記錄下來 functio...