劍指Offer 031 連續子陣列的最大和

2021-07-11 13:01:15 字數 3783 閱讀 2112

牛客oj:連續子陣列的最大和

九度oj:

github**: 031-連續子陣列的最大和

csdn題解:劍指offer–031-連續子陣列的最大和

牛客oj

九度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。我們注意到由於此前累計的和是 ...