連續子陣列最大和問題
1. 問題描述
輸入一個整形陣列,求陣列中連續的子陣列使其和最大。比如,陣列x
應該返回 x[2..6]的和187.
2. 問題解決
我們很自然地能想到窮舉的辦法,窮舉所有的子陣列的之和,找出最大值。
窮舉法
i, j的for迴圈表示x[i..j],k的for迴圈用來計算x[i..j]之和。
maxsofar = 0
for i = [0, n)
for j = [i, n)
sum = 0
for k = [i, j]
sum += x[k]
/* sum is sum of x[i..j] */
maxsofar = max(maxsofar, sum)
有三層迴圈,窮舉法的時間複雜度為O(n3)O(n3)
對窮舉法的改進1
我們注意到x[i..j]之和
= x[i..j-1]之和 + x[j]
,因此在j的for迴圈中,可直接求出sum。
maxsofar = 0
for i = [0, n)
sum = 0
for j = [i, n)
sum += x[j]
/* sum is sum of x[i..j] */
maxsofar = max(maxsofar, sum)
顯然,改進之後的時間複雜度變為O(n2)O(n2)。
對窮舉法的改進2
在計算fibonacci數時,應該還有印象:用一個累加陣列(cumulative array)記錄前面n-1次之和,計算當前時只需加上n即可。同樣地,我們用累加陣列cumarr記錄:cumarr[i]
= x[0] + . . . +x[i]
x
[i.. j]之和 = cumarr[j] -cumarr[i - 1]
。
cumarr[-1] = 0
for i = [0, n)
cumarr[i] = cumarr[i-1] + x[i]
maxsofar = 0
for i = [0, n)
for j = [i, n)
sum = cumarr[j] - cumarr[i-1]
/* sum is sum of x[i..j] */
maxsofar = max(maxsofar, sum)
時間複雜度依然為O(n2)O(n2)。
分治法
所謂分治法,是指將一個問題分解為兩個子問題,然後分而解決之。具體步驟如下:
-
先將陣列分為兩個等長的子陣列a, b;
-
分別求出兩個陣列a,b的連續子陣列之和;
-
還有一種情況比較容易忽略:有可能最大和的子陣列跨越兩個陣列;
-
最後比較mama, mbmb, mcmc,取最大即可。
在計算mcmc時,注意:mcmc必定包含總區間的中間元素,因此求mcmc等價於從中間元素開始往左累加的最大值
+ 從中間元素開始往右累加的最大值
。
float maxsum3(l, u)
if (l > u) /* zero elements */
return 0
if (l == u) /* one element */
return max(0, x[l])
m = (l + u) / 2
/* find max crossing to left */
lmax = sum = 0
for (i = m; i >= l; i--)
sum += x[i]
lmax = max(lmax, sum)
/* find max crossing to right */
rmax = sum = 0
for i = (m, u]
sum += x[i]
rmax = max(rmax, sum)
return max(lmax+rmax,
maxsum3(l, m),
maxsum3(m+1, u));
容易證明,時間複雜度為O(n∗logn)O(n∗log n)。
Kadane演算法
Kadane演算法又被稱為掃描法,該演算法用到了一個啟發式規則:如果前面一段連續子陣列的和小於0,那麼就丟棄它。其實也蠻好理解的,舉個簡單例子,比如:陣列-1,
2, 3
,-1為負數,為了使得子陣列之和最大,顯然不應當把-1計入進內。
max_ending_here記錄前面一段連續子陣列之和。
Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + x[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far
只遍歷了一遍陣列,因此時間複雜度為O(n)O(n)。
3. 參考資料
[1] Jon Bentley, Programming Pearls.
[2] GeeksforGeeks, Largest Sum Contiguous Subarray.
相關推薦
劍指offer:(31)時間效率 :連續子陣列最大和
package jianzhioffer; public class Solution31 { //動態規劃:就是將中間值儲存下來 public static int FindGreatestSumOfSubArray(int[] array) { if (array == null
連續子陣列最大和O(n)兩種解法:雙指標 動態規劃
題目描述 HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7
【劍指offer】連續子陣列最大和
題目:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。給一個數組,返回它的最大連續子序
動態規劃--求目標值問題、找零錢問題以及求連續子陣列最大和 --java
1、動態規劃一般可分為線性動規,區域動規,樹形動規,揹包動規四類。 舉例: 線性動規:攔截導彈,合唱隊形,挖地雷,建學校,劍客決鬥等; 區域動規:石子合併, 加分二叉樹,統計單詞個數,炮兵佈陣等; 樹形動規:貪吃的九頭龍,二分查詢樹,聚會的歡樂,數字三角形等;
牛客網 《劍指Offer》程式設計 30.連續子陣列最大和
題目描述 HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,
常見演算法 - 連續子陣列最大和
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if(array.length == 0){ return 0; }
陣列連續子陣列最大和最大乘積
題目:給定一個數組,要求其連續子陣列的最大和。如陣列為{6,-3,-2,7,-15,1,2,2},連續子陣列的最大和為8(從第0個開始,到第3個為止) 解法1:首先最容易想到的便是利用列舉的方法,枚舉出所有可能大小的連續子陣列的和,然後選出其中最大的一個。即從連續子陣列的大
求某個數組裡連續子陣列最大和的幾個演算法
注意:這裡的陣列元素,有可能全為負。這樣,所謂的: int find_max_array(const vector<int> &a) { int max_sum = 0; int this_sum = 0; fo
動態規劃演算法(連續子陣列最大和,O(N)時間複雜度O(1)空間複雜度) 【更新於:2018-05-13】
這個題目最早在13年阿里筆試出現,直到前兩天面試另一家電商又出現,哎,欠的都是要還的。 這個問題的思路如下:一維陣列的下標連續的元素構成連續子陣列,求所有連續子陣列中和最大的那個子陣列。 解析:2018-11-08 1 首先這個問題要轉化為Q(n)的問題,對於Q(n)的
連續子陣列最大和
題目描述: 輸入一個整形陣列,數組裡有正數也有負數。 陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。 求所有子陣列的和的最大值。要求時間複雜度為O(n)。 例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10,
連續子陣列最大和問題
1. 問題描述 輸入一個整形陣列,求陣列中連續的子陣列使其和最大。比如,陣列x 應該返回 x[2..6]的和187. 2. 問題解決 我們很自然地能想到窮舉的辦法,窮舉所有的子陣列的之和,找出最大值。 窮舉法 i, j的for迴圈表示x[i..j],k的for
python實現求連續子陣列最大和
問題描述:例如:[6,-3,-2,7,-15,1,2,2]求連續子陣列中的最大和,此陣列中最大和為8,從arr[0]到arr[3]。其餘位置都比這個要小。最大連續子陣列的特點:(1)第一個不為負數(2)如果前面數的累加加上當前數小於當前數,說明這次累加對總體的結果是無效的;如
迴圈陣列的子陣列最大和
一。實驗要求 1.輸入一個整型陣列,數組裡有正數也有負數,陣列中一個或多個整陣列成一個整陣列,每個子陣列都有一個和。 2.陣列可以首位相連,允許A【i-1】,....,A[n-2],A[0]........A[j-1]和最大 3.返回最大子陣列的位置,求最大子陣列的和. 二、實驗思路 迴圈陣列,也就
連續子序列最大和問題---python實現
連續子序列最大和問題—python實現 問題:連續子序列最大和 給定一個數字序列[A1A2A3…An],求i,j(1<=i<=j<=n)使得Ai…Aj和最大, 輸出這個最大和(連續大子序列最大和) 例如: 輸入: L=[-2 ,6,
【演算法之陣列(一)】求子陣列最大和的解決方法詳解
題目: 輸入一個整形陣列,數組裡有正數也有負數。 陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。 求所有子陣列的和的最大值。 例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2, 因此
Maximum Subarray連續子序列最大和 -- LeetCode(經典動態規劃)
原題連結: http://oj.leetcode.com/problems/maximum-subarray/這是一道非常經典的動態規劃的題目,用到的思路我們在別的動態規劃題目中也很常用,以後我們稱為”區域性最優和全域性最優解法“。基本思路是這樣的,在每一步,我們維護兩個變數,一個是全域性最優,就是到當前元
連續子序列最大和問題的四種經典解答
問題描述 給定(可能是負的)整數序列A1, A2,...,AN, 尋找(並標識)使Sum(Ak)(k >=i, k <= j)的值最大的序列。如果所有的整數都是負的,那麼連續子序列的最大和是那個最大的負數項。最好給出給出最大和連續子序列!! 1 暴力破
動態規劃——連續子序列最大和
題目描述: 輸入一個整型陣列,數組裡有正數也有負數。 陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。 求所有子陣列的和的最大值。要求時間複雜度為O(n)。 例如輸入的陣列為1,
六種姿勢拿下連續子序列最大和問題,附虛擬碼(以HDU 1003 1231為例)
問題描述: 連續子序列最大和,其實就是求一個序列中連續的子序列中元素和最大的那個。 比如例如給定序列: { -2, 11, -4, 13, -5, -2 } 其最大連續子序列為{ 11, -4, 13 },最大和
求陣列內子陣列最大的和(Maximum Subarray )
來源:https://leetcode.com/problems/maximum-subarray/#/descriptionFind the contiguous subarray within an array (containing at least one numb