求陣列子串行的最大和

2022-09-23 23:24:11 字數 1778 閱讀 3897

一、問題描述

輸入乙個整形陣列,陣列裡可以有正數或負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o(n)。

例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,因此輸出為該子陣列的和18。

第一次遇到這道題是參加x迅的筆試。題目中給出了兩種解法,讓填空。

二、簡單解

拿到這道題,如果不考慮效能和複雜度,最簡單的方法就是窮舉。窮舉出所有的子陣列,並求出他們的和,返回最大值。不過,複雜度為o(n3),不符合題目的要求(複雜度on)

[cpp] view plaincopyprint?

int max_sum(int *arr, int len) 

} } 

} if(max == 0)  

return max; 

} int max_sum(int *arr, int len)

}} }

if(max == 0)

return max;

}三、複雜度為n2的解

觀察上面的**,我們使用了3個for迴圈。其中最內側的for迴圈主要是控制每個字序列的長度,由於我們在計算的過程中,已經儲存了當前最大字序列和,字序列的長度n對我們來說意義不大,因此完全可以撤消最內側的迴圈。只按每個字序列起始位置來計算最大和。這樣得到乙個複雜度為n2的解。

[cpp] view plaincopyprint?

int max_sum2(int *arr, int len) 

} } 

if(max == 0)  

return max; 

} int max_sum2(int *arr, int len)

} }if(max == 0)

return max;

}四、更低複雜度的探索

至此,我們已經得到乙個複雜度為n2的解法。那麼有沒有更低複雜度的演算法呢?在n2的演算法中,我們遍歷了從0到len-1開始的字序列,求出每種情況下得到的最大字序列和。那麼我們有沒有可能去掉這個迴圈呢?考慮使用動態規劃的思想,記max_sum[i]為從0到i的子串行的最大和,那麼可以得到遞推式:

[cpp] view plaincopyprint?

if max_sum[i] > 0   

then   

if arr[i+1] > 0   

then max_sum[i+1] = max_sum[i] + arr[i+1];   

else   

max_sum[i+1] = max(0, arr[i+1])  

if max_sum[i] > 0 

then 

if arr[i+1] > 0 

then max_sum[i+1] = max_sum[i] + arr[i+1]; 

else 

max_sum[i+1] = max(0, arr[i+1])

利用這種思路得到乙個線性時間的解答:

[cpp] view plaincopyprint?

int max_sum3(int *arr, int len)  

if(sum > max) 

} if(max == 0)  

return max; 

} int max_sum3(int *arr, int len)

if(sum > max)

} if(max == 0)

return max;

}至此,我們得到乙個時間複雜度on,空間複雜度o1的解。

求陣列子串行的最大和

輸入乙個整形陣列,陣列裡可以有正數或負數 陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求 時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此輸出為該子陣列的和18。第一次遇到這道題是參加x迅...

求陣列非連續子串行的最大和

題目描述 1.乙個整數陣列l,如 l 2,3,3,50 求 l的乙個非連續子串行,使其和最大,輸出最大子串行的和。這裡非連續子串行的定義是,子串行中任意相鄰的兩個數在原序列裡都不相鄰。例如,對於 l 2,3,3,50 輸出 52 分析 很明顯,該列表最大非連續子串行為 2,50 測試例子 l 2,3...

求陣列中連續子陣列的最大和

思路 計算出任意i到j之間連續子陣列的和再比較必然能得到最大值,但時間複雜度為o n 2 我們希望能找出線性時間的演算法。我們注意到,假如陣列中全為正數,那麼最大和必然為全部數相加 如果陣列中有負數,並且如果加上某個負數,子陣列的和小於0,則最大和子陣列必然不包含這個負數。基於此,給出以下 incl...