一、題目
輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o(n)。
例子說明:
例如輸入的陣列為,和最大的子陣列為{3, 10, -4, 7, 2}。因此輸出為該子陣列的和18 。
二、解題思路
解法一:舉例分析陣列的規律。
我們試著從頭到尾逐個累加示例陣列中的每個數字。初始化和為0。第一步加上第乙個數字1, 此時和為1。接下來第二步加上數字-2,和就變成了-1。第三步刷上數字3。我們注意到由於此前累計的和是-1 ,小於0,那如果用-1 加上3 ,得到的和是2 , 比3 本身還小。也就是說從第乙個數字開始的子陣列的和會小於從第三個數字開始的子陣列的和。因此我們不用考慮從第乙個數字開始的子陣列,之前累計的和也被拋棄。
我們從第三個數字重新開始累加,此時得到的和是3 。接下來第四步加10,得到和為13 。第五步加上-4, 和為9。我們發現由於-4 是乙個負數,因此累加-4 之後得到的和比原來的和還要小。因此我們要把之前得到的和13 儲存下來,它有可能是最大的子陣列的和。第六步加上數字7,9 加7 的結果是16,此時和比之前最大的和13 還要大, 把最大的子陣列的和由13更新為16。第七步加上2,累加得到的和為18,同時我們也要更新最大子陣列的和。第八步加上最後乙個數字-5,由於得到的和為13 ,小於此前最大的和18,因此最終最大的子陣列的和為18 ,對應的子陣列是{3, 10, -4, 7, 2}。
解法二: 應用動態歸劃法。
可以用動態規劃的思想來分析這個問題。如果用函式f(i)表示以第i個數字結尾的子陣列的最大和,那麼我們需要求出max[f(i)],其中0 <= i < n。我們可用如下邊歸公式求f(i):
這個公式的意義:當以第i-1 個數字結尾的子陣列中所有數字的和小於0時,如果把這個負數與第i個數累加,得到的結果比第i個數字本身還要小,所以這種情況下以第i個數字結尾的子陣列就是第i個數字本身。如果以第i-1 個數字結尾的子陣列中所有數字的和大於0 ,與第i 個數字累加就得到以第i個數字結尾的子陣列中所有數字的和。
public
class
test
// 記錄最大的子陣列和,開始時是最小的整數
int max = integer.min_value;
// 當前的和
int curmax =0;
// 陣列遍歷
for(
int i : arr)
// 如果當前和大於0,累加當前和
else
// 更新記錄到的最在的子陣列和
if(max < curmax)
}return max;
}}
7 連續子陣列的最大和(子陣列 最大和)
題目 給乙個陣列,讓求連續陣列元素的最大和。public int maxsumofsubarray int arr 思路 連續子陣列的最大和動態規劃 dp i dp i 表示以arr i 結尾的連續子陣列的最大和。arr i 必須加上,就不判斷arr i 是正還是負。dp i 等於arr i 加上以...
27 連續子陣列的最大和
連續子陣列的最大和 hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量的最大和為8...
30 連續子陣列的最大和
題目描述 hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量的最大和為8 從第0個...