程式設計師程式設計藝術 第七章 求連續子陣列的最大和

2021-06-14 02:10:33 字數 3519 閱讀 1848

前奏第一節、求子陣列的最大和

3.求子陣列的最大和

題目描述:

輸入乙個整形陣列,陣列裡有正數也有負數。

陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。

求所有子陣列的和的最大值。要求時間複雜度為o(n)。

例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,

因此輸出為該子陣列的和18。

分析:這個問題在各大公司面試中出現頻率之頻繁,被人引用次數之多,非一般面試題可與之匹敵。單憑這點,就沒有理由不入選狂想曲系列中了。此題曾作為本人之前整理的微軟100題中的第3題,至今反響也很大。ok,下面,咱們來一步一步分析這個題:

1、求乙個陣列的最大子陣列和,如此序列1, -2, 3, 10, -4, 7, 2, -5,我想最最直觀也是最野蠻的辦法便是,三個for迴圈三層遍歷,求出陣列中每乙個子陣列的和,最終求出這些子陣列的最大的乙個值。

記sum[i, …, j]為陣列a中第i個元素到第j個元素的和(其中0 <= i <= j < n),遍歷所有可能的sum[i, …, j],那麼時間複雜度為o(n^3):

//本段**引自程式設計之美

int maxsum(int* a, int n)

if(sum > maximum)

maximum = sum;

sum=0;   //這裡要記得清零,否則的話sum最終存放的是所有子陣列的和。也就是程式設計之美上所說的bug。多謝蒼狼。}}

return maximum;

}

2、其實這個問題,在我之前上傳的微軟100題,答案v0.2版[第1-20題答案],便直接給出了以下o(n)的演算法:

//updated,2011.05.25.

#include 

intmaxsum(

int* a, 

intn)  

return

sum;  

}  int

main()  

;  //int a=;  //測試全是負數的用例

cout<

return

0;  

}  /*-------------------------------------

解釋下:

例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,

那麼最大的子陣列為3, 10, -4, 7, 2,

因此輸出為該子陣列的和18。

所有的東西都在以下倆行,

即:b  :  0  1  -1  3  13   9  16  18  13  

sum:  0  1   1  3  13  13  16  18  18

其實演算法很簡單,當前面的幾個數,加起來後,b<0後,

把b重新賦值,置為下乙個元素,b=a[i]。

當b>sum,則更新sum=b;

若b----------------------------------*/

3、不少朋友看到上面的答案之後,認為上述思路2的**,沒有處理全是負數的情況,當全是負數的情況時,我們可以讓程式返回0,也可以讓其返回最大的那個負數,下面便是前幾日重寫的,修改後的處理全是負數情況(返回最大的負數)的**:

//july、updated,2011.05.25。

#include 

#define n 4           //多定義了乙個變數

intmaxsum(

inta[n])    

//於此處,你能看到上述思路2**(指標)的優勢

return

max;  

}  int

main()  

;  cout<

return

0;  

}  

4、dp解法的具體方程:@flyinghearts:設sum[i] 為前i個元素中,包含第i個元素且和最大的連續子陣列,result 為已找到的子陣列中和最大的。對第i+1個元素有兩種選擇:做為新子陣列的第乙個元素、放入前面找到的子陣列。

sum[i+1] = max(a[i+1], sum[i] + a[i+1])

result = max(result, sum[i])

擴充套件:

1、如果陣列是二維陣列,同樣要你求最大子陣列的和列?

2、如果是要你求子陣列的最大乘積列?

3、如果同時要求輸出子段的開始和結束列?

第二節、data structures and algorithm analysis in c

下面給出《data structures and algorithm analysis in c》中4種實現。

//感謝網友firo

//july、2010.06.05。

//algorithm 1:時間效率為o(n*n*n)

intmaxsubsequencesum1(

const

inta,

intn)  

return

maxsum;  

}  //algorithm 2:時間效率為o(n*n)

intmaxsubsequencesum2(

const

inta,

intn)  

}  return

maxsum;  

}  //algorithm 3:時間效率為o(n*log n)

//演算法3的主要思想:採用二分策略,將序列分成左右兩份。

//那麼最長子序列有三種可能出現的情況,即

//只出現在左部分.

//只出現在右部分。

//出現在中間,同時涉及到左右兩部分。

//分情況討論之。

static

intmaxsubsum(

const

inta,

intleft,

intright)  

maxrightbordersum=0;  

rightbordersum=0;  

for(i=center+1;i<=right;i++)  

intmax1=maxleftsum>maxrightsum?maxleftsum:maxrightsum;  

intmax2=maxleftbordersum+maxrightbordersum;  

return

max1>max2?max1:max2;  

}  //algorithm 4:時間效率為o(n)

//同上述第一節中的思路3、和4。

intmaxsubsequencesum(

const

inta,

intn)  

return

maxsum;  

}   

本章完。

程式設計師程式設計藝術 第七章 求連續子陣列的最大和

前奏 第一節 求子陣列的最大和 3.求子陣列的最大和 題目描述 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7...

程式設計師程式設計藝術 第七章 求連續子陣列的最大和

前奏 第一節 求子陣列的最大和 3.求子陣列的最大和 題目描述 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7...

程式設計師法則 第七章 遊戲

第七章 遊戲 程式不是年輕的專利,但是,他屬於年輕。離開了軟體協會的那夥人,我深深的吸了口氣,想不到乙個大學竟然都如此藏龍臥虎,我不加油不行啊。附近一塊大大的牌子進入了我的視線,電子競技協會,恩?這是幹什麼的,好象和計算機也有關係啊,我跑過去看了起來,cs,魔獸,星際。和我們一起進入競技遊戲的世界。...