。
前奏第一節、求子陣列的最大和
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):
//本段**引自程式設計之美2、其實這個問題,在我之前上傳的微軟100題,答案v0.2版[第1-20題答案],便直接給出了以下o(n)的演算法:int maxsum(int* a, int n)
if(sum > maximum)
maximum = sum;
sum=0; //這裡要記得清零,否則的話sum最終存放的是所有子陣列的和。也就是程式設計之美上所說的bug。多謝蒼狼。}}
return maximum;
}
//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,魔獸,星際。和我們一起進入競技遊戲的世界。...