JAVA面向物件01
阿新 • • 發佈:2020-10-04
實踐題目名稱
最大子列和問題
問題描述
給定K個整陣列成的序列{ N1, N2, ..., NK },“連續子列”被定義為{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列元素的和中最大者。例如給定序列{ -2, 11, -4, 13, -5, -2 },其連續子列{ 11, -4, 13 }有最大的和20。要求編寫程式,計算給定整數序列的最大子列和。
演算法描述
如圖,採用分治法和二分遞迴來出目標子區間,將目標的子段分為三種可能性
- 橫跨mid兩端
- 只在mid左邊
- 只在mid右邊
每次選取一個mid,求出mid向左的最大連續子序列和與mid向右的最大連續子序列和,相加得到跨過mid兩端的最大子段和。將其與左邊和右邊的最大欄位和進行比較,選出三者中最大的那個。而左邊和右邊的最大子段和則是通過遞迴,將其再次看成一個可以劃分mid的子段求出其範圍的最大子段得出。
通過遞迴每次得出最大的子段和,遞迴到最後出口就是整個數列最大的子段和。
複雜度分析
- 時間複雜度
由於是分治法,通過二分每次得出2個規模為原來二分之一的問題來求解,所以可以寫出下列表達式
T(n) = 2T(n/2)+O(n)
通過主定理可以得出d=logba=log22=1
所以時間複雜度為O(nlogn)
- 空間複雜度
由於這個演算法都是在原陣列上進行操作,所以演算法的空間複雜度為O(1)
心得體會
一開始對這個演算法存在疑惑,認為這種方法不能考慮周全,可能存在欠考慮的情況。後來認真理解清楚後才發現這種分治法對問題進行了很好的規模與情況分類,也做到了考慮到所有情況,不禁感到精妙。
所以還是要加強自己在寫程式碼前對演算法的理解程度,想清楚了再開始寫,才不會中間出現很多的bug,同時搭檔2人之間也要交流清楚,才能提高效率和精確度。