牛客oj:連續子陣列的最大和牛客oj九度oj:
github**: 031-連續子陣列的最大和
csdn題解:劍指offer–031-連續子陣列的最大和
九度oj
csdn題解
github**
031-連續子陣列的最大和
1372-連續子陣列的最大和
劍指offer–031-連續子陣列的最大和
031-連續子陣列的最大和
您也可以選擇回到目錄-劍指offer–題集目錄索引
題目描述
hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。例如:,今天測試組開完會後,他又發話了:
在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。
但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?
連續子向量的最大和為8(從第0個開始,到第3個為止)。
你會不會被他忽悠住?
最直接的方法就是找出所有的子陣列,然後求其和,取最大
如果每個子陣列都遍歷求和,該方法的複雜度為o(n^3),仔細考慮,在遍歷過程中,這些子陣列的和是有重複計算的:下標i與j之間的區間和sum[i,j]=sum[i,j-1]+arr[j]。
於是子陣列和的求法不必每次都遍歷,演算法複雜度可以降為o(
n2)
**如下:
#include
#include
using
namespace
std;
// 除錯開關
#define __tmain main
#ifdef __tmain
#define debug cout
#else
#define debug 0 && cout
#endif // __tmain
class solution
int sum, maxsum = int_min;
for(unsigned
int i = 0; i < array.size( ); i++)}}
return maxsum;
}};int __tmain( )
; vector
vec1(arr1, arr1 + sizeof(arr1)/sizeof(arr1[0]));
cout
<
vector
vec2(arr2, arr2 + sizeof(arr2)/sizeof(arr2[0]));
cout
<
0;}
解體思路:
如果用函式f(i)表示以第i個數字結尾的子陣列的最大和,那麼我們需要求出max(f[0…n])。我們可以給出如下遞迴公式求f(i)
這個公式的意義:
當以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)小於0時,如果把這個負數和第i個數相加,得到的結果反而不第i個數本身還要小,所以這種情況下最大子陣列和是第i個數本身。
如果以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)大於0,與第i個數累加就得到了以第i個數結尾的子陣列中所有數字的和
class solution
#ifdef __tmain
int temp, start, end;
#endif // __tmain
int maxsum = int_min;
dp[0] = array[0];
for(unsigned
int i = 1; i < array.size( ); i++)
else
if(dp[i] > maxsum)
}debug
如果希望達到o(n)時間複雜度,我們就應該能夠想到我們只能對整個陣列進行一次掃瞄,在掃瞄過程中求出最大連續子串行和以及子串行的起點和終點位置。假如輸入陣列為,我們嘗試從頭到尾累加其中的正數,
初始化和為0,第一步加上1,此時和為1,第二步加上-2,此時和為-1,第三步加上3,此時我們發現-1+3=2,最大和2反而比3乙個單獨的整數小,這是因為3加上了乙個負數,發現這個規律以後我們就重新作出累加條件
這個方法其實就是動態規劃演算法的改進
思路如下
class solution
int sum = 0, maxsum = int_min;
for(unsigned
int i = 0; i < array.size( ); i++)
else
if(sum > maxsum) /// 否則的話累計當前和
}/// 如果陣列最大值大於0, 那麼我們就直接返回累計的最大和
/// 如果陣列最大值為負數, 說明整個陣列都是負數, 那麼就返回陣列最大值
return maxsum;}};
但是這個由乙個問題,如果整個陣列的資料全是負數,那麼我們的maxsum無法進行累計,最後仍為0。
這個問題怎麼解決呢?
整個陣列全是負數,那麼最大值也是負數,而這個最大值正好是陣列連續子陣列的最大和,因此我們維護乙個最大值maxnum,即可
return (maxnum > 0) ? maxsum : maxnum;
完整**如下
class solution
int maxnum = int_min;
int sum = 0, maxsum = int_min;
for(unsigned
int i = 0; i < array.size( ); i++)
else
if(sum > maxsum) /// 否則的話累計當前和
/// 儲存資料中的最大值
/// 這種情況下是為了排除整個陣列全為負數的特殊情況
if(array[i] > maxnum)
}/// 如果陣列最大值大於0, 那麼我們就直接返回累計的最大和
/// 如果陣列最大值為負數, 說明整個陣列都是負數, 那麼就返回陣列最大值
return (maxnum > 0) ? maxsum : maxnum;}};
但是其實有更好的辦法,每次弄完後我們無需系那個sum置為0,而是需要從新的位置(下乙個位置)開始,因此此時其實sum=array[i + 1];
那麼我們直接用下面的**即可
class solution
int maxnum = int_min;
int sum = 0, maxsum = int_min;
for(unsigned
int i = 0; i < array.size( ); i++)
else
debug <
< maxsum)
}return maxsum;
}};
最大子陣列和(最大子串行和 | 連續子陣列最大和)
求連續子陣列的最大和
程式設計師程式設計藝術:第七章、求連續子陣列的最大和
">
劍指offer 05 連續子陣列最大和
hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量的最大和為8 從第0個開始,到第...
劍指offer系列之29 連續子陣列的最大和
題目描述 輸入乙個整型陣列,陣列中乙個或連續多個整數組成乙個子陣列,求所有子陣列的和的最大值,要求時間複雜度為o n 思路 舉例分析陣列的規律,這實際上是乙個逐步比較的過程,假設累加進行到某一步,繼續累加下乙個數的時候發現和變小了,就應該重新計算當前累加的和,這實際上就是乙個重新賦值的過程。如果累加...
劍指Offer 程式設計題31(連續子陣列的最大和)
例如輸入的陣列為,和最大的子陣列為 3,10,4,7,2 因此輸出為該子陣列的和18 解法一 舉例分析陣列的規律。我們試著從頭到尾逐個累加示例陣列中的每個數字。初始化和為0。第一步加上第乙個數字1,此時和為1。接下來第二步加上數字 2,和就變成了 1。第三步刷上數字3。我們注意到由於此前累計的和是 ...