演算法導論 最大子陣列問題的三種解法

2021-09-25 22:21:34 字數 2327 閱讀 1844

【演算法導論】最大子陣列問題的三種解法

標籤(空格分隔):【演算法導論】

首先補充兩個數學公式:

a lo

gbc=

clog

baa^ = c^

alogb​

c=cl

ogb​alo

g(n!

)=θ(

nlog

n)log(n!) = \theta(nlogn)

log(n!

)=θ(

nlog

n)什麼是最大子陣列問題?

給定一陣列a, 尋找a中和最大的非空連續子陣列。

例如:輸入: a = [-2,1,-3,4,-1,2,1,-5,4],

輸出: 6

解釋: 連續子陣列 [4,-1,2,1] 的和最大為 6。

針對該問題,現給出三種解法。

解法一:暴力求解(最直觀的方法)

對於長度為 n 的陣列a, 任選兩個位置作為區間起始和末尾,計算該區間所代表的的子陣列的和,選擇最大的乙個。

符合條件的位置對數有cn2

c_n^2

cn2​

個,因此時間複雜度為o(n

2)o(n^2)

o(n2).

由於計算區間和時需要借助乙個輔助陣列,因此空間複雜度為o(n

)o(n)

o(n)

**:

int find_max_subarray( vector& a)
解法二:分治演算法(不好理解且**長)

假設將陣列a[low, …, high] 以位置mid處劃分為兩個長度大致相等的子陣列,則最大子陣列a[i, …, j] 必定為以下三種情況之一:

最大子陣列完全位於 a[low, …, mid] 之間,即 low

≤i≤j

≤mid

low \le i \le j \le mid

low≤i≤

j≤mi

d.最大子陣列完全位於 a[mid, …, high] 之間,即 mid

≤i≤j

≤hig

hmid \le i \le j \le high

mid≤i≤

j≤hi

gh.最大子陣列跨越了 mid 位置,即 low

≤i≤m

idhigh

low \le i \le mid < j \le high

low≤i≤mid

high

. **:

int find_max_subarray( vector& a, int left, int right)
sum = sum_max; // 向另外一側移動時需要初始化

for( int i = mid + 1; i <= right; i++)

return max( max( l, r), sum_max);

}// 在主程式中輸入的引數應該為 find_max_subarray(a, 0, a.size() - 1)測試用例:

注:改**已ac leetcode 第53題。

時間複雜度為:o(n

logn

)o(nlogn)

o(nlog

n)解法三:動態規劃(不易理解但短小精悍)

初始化變數 sum = 0, 從頭遍歷陣列,對於每乙個元素 a[i], 變數 sum += a[i], 一旦 sum < 0, 立即讓 sum = 0, 並向後移動乙個元素,直到陣列尾部。最終選擇最大的 sum 值。

為直觀起見,以陣列 a = [-2, 3, -1, 2, -3] 為例:

}測試用例:

注:改**已ac leetcode 第53題。

由於只是遍歷陣列,因此時間複雜度為 o(n

演算法導論之三最大子陣列問題

最大子陣列是陣列a的和最大的非空連續子陣列。只有當陣列中包含負數時,最大子陣列問題才有意義。注意將實際問題轉化為數學問題!使用分治策略的求解方法 為尋找a low.high 的最大子陣列,其 位置記為mid,然後考慮求解兩個子陣列a low.mid 和a mid 1.high a low.high ...

最大子陣列問題 演算法導論

分治法思想 分解 子陣列一定被原陣列左邊或者右邊包含,或者跨越原陣列mid下標。解決 前兩種完全包含的情況形成子問題遞迴求解,並且縮小了問題規模,後一種是我們要解決的問題。合併 剩餘的問題是求跨越mid的最大子陣列,並且從三種情況中選出和最大的。另外 算導中偽 返回的是三元組,這裡實現的話用結構體返...

最大子陣列問題的三種解法

最大子陣列問題 在乙個數列當中尋找乙個子數列,使得這個子數列的元素之和最大。為了使 簡單化,在這裡我們只求出最大值。暴力搜尋,即在c n,2 種可能的方法中尋找符合題意得一種,顯然時間複雜度為 n include include using namespace std int a 16 int ma...