三種演算法求解乙個陣列的子陣列最大和

2021-06-16 19:04:31 字數 2159 閱讀 2834

from 

題目:要求乙個陣列連續下標和的最大值,陣列的元素可正、可負、可為零,例如-2,5,3,-6,4,-8,6將返回8。

這題是很經典的一道面試題,也有各種解法,從演算法分析上,時間複雜度也有很大差別,下面我就給出三種不同的解法。

方法一:暴力列舉法

此種方法最簡單,我想應該也是每個人拿到題目想到的第一種解法了,學過一點程式設計的人都應該能編出此類程式。

記sum[i..j]為陣列中第i個元素到第j個元素的和(其中0<=i

偽**如下:

int maxsubarray(int *a,int n)

此種方法的時間

複雜度為o(n2)

,顯然不是一種很好的辦法,也不是公司面試希望你寫出這樣的程式的。

具體實現**如下:

#include #include #include #include #include using namespace std;

const int inf=0x7fffffff;

int max_sub_array(int arr,int n,int &left,int &right)}}

return maxium;

}

方法二:分支界定

這裡再介紹一種更高效的演算法,時間

複雜度為o(nlogn)

。這是個分治的思想,解決複雜問題我們經常使用的一種思維方法——分而治之。

而對於此題,我們把陣列a[1..n]分成兩個相等大小的塊:a[1..n/2]和a[n/2+1..n],最大的子陣列只可能出現在三種情況:

a[1..n]的最大子陣列和a[1..n/2]最大子陣列相同;

a[1..n]的最大子陣列和a[n/2+1..n]最大子陣列相同;

a[1..n]的最大子陣列跨過a[1..n/2]和a[n/2+1..n]

前兩種情況的求法和整體的求法是一樣的,因此遞迴求得。

第三種,我們可以採取的方法也比較簡單,沿著第n/2向左搜尋,直到左邊界,找到最大的和maxleft,以及沿著第n/2+1向右搜尋找到最大和maxright,那麼總的最大和就是maxleft+maxright。

而陣列a的最大子陣列和就是這三種情況中最大的乙個。

偽**如下:

int maxsubarray(int *a,int l,int r)

}int max_right=-inf;

sum_both=0;

for(int i=mid+1;i<=r;i++)

}sum_both=max_left+max_right;

if(suml方法三:動態規劃

這算是乙個經典的動態規劃的題目了,如果不知道動態規劃可以先不去理解這個名詞。用通俗點的語言描述這個演算法就是:

令cursum(i)表示陣列下標以i為起點的最大連續下標最大的和,而maxsum(i)表示前i個元素的最大子陣列之和。那麼我們就可以推出下乙個maxsum(i+1)應該為cursum(i+1)和maxsum(i)中選取乙個最大值。遞推式為:

cursum(i) = max;

maxsum(i) = max;

偽**為:

int maxsubarray(int *a,int n)

這種演算法時間複雜度只是o(n)

,效果非常好!

具體實現**如下:

int max_sub_array_(int arr,int n,int& left,int&right)

}return maxsum;

}void test1()

; int len=sizeof(arr)/sizeof(arr[0]);

int left,right;

int sum;

cout<

copy(arr,arr+len,ostream_iterator(cout, " "));

cout

cout<

其中test1函式是題目給出的陣列測試,test2是進行隨機產生數來測試。

大致的效果如下:

test1測試:

test2測試:

參考: 

三種演算法求解乙個陣列的子陣列最大和

題目 要求乙個陣列連續下標和的最大值,陣列的元素可正 可負 可為零,例如 2,5,3,6,4,8,6將返回8。這題是很經典的一道面試題,也有各種解法,從演算法分析上,時間複雜度也有很大差別,下面我就給出三種不同的解法。方法一 暴力列舉法 此種方法最簡單,我想應該也是每個人拿到題目想到的第一種解法了,...

建立乙個陣列有三種方法

1.宣告乙個陣列,宣告是用常量表示式指定陣列維數,然後可以勇敢數租明訪問數租元素。2.宣告乙個變長數租,宣告是用變數表示式指定陣列維數,然後用陣列名來訪問陣列元素 c99特性 double item n 如果n是乙個變數,c99之前不允許這樣做。3.宣告乙個指標,呼叫malloc 然後使用指標來訪問...

乙個陣列演算法題,利用遞迴 回溯求解

給你10 分鐘時間,根據上排給出十個數,在其下排填出對應的十個數 要求下排每個數都是先前上排那十個數在下排出現的次數。上排的十個數如下 0,1,2,3,4,5,6,7,8,9 舉乙個例子,數值 0,1,2,3,4,5,6,7,8,9 分配 6,2,1,0,0,0,1,0,0,0 0 在下排出現了 6...