0 引言
題目:hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,
並期望旁邊的正數會彌補它呢?例如:,連續子向量的最大和為8(從第0個開始,到第3個為止)。
給乙個陣列,返回它的最大連續子串行的和,你會不會被他忽悠住?(子向量的長度至少是1)
1 舉例/測試用例設定
(1)全是非負數的情況:
全部相加即可得到最大和,也就是說全體序列就是最大和序列
(2)全是非正數的情況:
某個最小的數即為最大連續子串行
(3)既有正數又有負數以及0的情況 :
1)將序列劃分為不同的子串行,劃分的依據是符號是否改變(從 「+ /0」 變為 「-」 或者 從「-/0」變為 「+」 ),轉化為
2)把滿足從0或者正數開始,從0或者正數結束的所有序列全部列舉出來,最後找到乙個最大的序列,就是要求的結果序列。
1. 12,sum = 12
2. 12-》-14-》14,sum = 12
3. 12-》-14-》14-》-18-》7,sum = 1
4. 14 ,sum = 14
5. 14-》-18-》7, sum = 3
6. 7 , sum = 7
7. 通過比較,得出最大連續子串行的和為14
2 具體例子抽象分析
通過1中的分析,可是演算法應當分為以下兩步進行
(1)對整個序列進行區域性融合,利用額外的空間把融合序列儲存起來 vectormyarray ,得到的序列具有以下特點:
1. 不包含0;
2. 奇偶相間;
(2)以開始和結束的值 >=0 為條件,計算所有的可能序列和
(3)如果所有的值均小於等於0,則返回整個序列中最大的數即可
3 demo
寫了一版非常粗糙的**,勉強除錯通過了,明天再優化一下,先貼上出來
int findgreatestsumofsubarray(vectorarray)if(maxsum <= 0
)
return
maxsum;
//若存在正數
//1. 區域性融合,將正數,負數和0分開融合,同時0不加入序列
vectormyarray;
for(int i=0;i}
else
}
}if(j ==array.size())
}//2. 遍歷求解最大連續子串行的和
//初始化maxsum
intbegin;
for(int i=0;i)
}for(int i=begin;i2
)
}return
maxsum;
}
4 優化
**毫無疑問有很多需要改進的地方,本身思路就不是很清晰,何況寫**的能力也不太行,結構很亂,看著著實費勁。。。參考了網友的**以及《劍指offer》,對
演算法作出如下調整。
(1)不對序列進行融合,轉而採取一次遍歷的方法,將演算法的複雜度從o((n/2)^2)降到o(n);
(2)一次遍歷的重點在於兩個變數:當前子串行最小和 currentsum以及maxsum。當currentsum <= 0時,拋棄當前currentsum,原因在於該當前和與訪問數相加得到的
和值一定小於訪問數。此時,應當將訪問數的值賦值給currentsum,從該數開始重新尋找最大和。
(3)當currentsum > maxsum時,更新該值.
demo如下:
int findgreatestsumofsubarray(vectorarray)return
maxsum;
}
對思路進行調整之後,寫完整段**只用了可能十來分鐘,相比於上個思路用了大概乙個半小時,這次可真是快太多了。。。所以說寫**思路才是決定性的。
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個...