問題分析:在乙個長為n的陣列a[1..n]中,找到這樣的i、j,使a[i...j]中元素的和最大,稱a[i...j]為最大子陣列。
演算法一(分治思想):
陣列a[low...high]的最大子陣列必然滿足三種情況:
1)子陣列在a[low...mid]中;
2)子陣列在a[mid+1,high]中;
3)子陣列跨越中點mid。
因此可以使用遞迴分治方法計算find_max(a, low, high),其中滿足:
find_max(a, low, high) = max(find_max(a, low, mid), find_max(a, mid+1, high), cross_max(a, low, mid, high))
cross_max(a, low, mid, high)是為了找到子陣列跨越中點時的最大情況。
使用c++實現,**如下:
#includeusingnamespace
std;
#define len 10
//定義輸出資訊資料結構,輸出子陣列左右下標,以及元素和
typedef struct
info*info, info1;
//建立輸出結構info
info createinfo(int a, int low, int
high)
//子陣列跨越中點時的最大情況
info find_cross_max(int a, int low, int mid, int
high)
}sum = 0
;
for(int i=mid+1;i<=high;i++)
}return
createinfo(a, left, right);}//
遞迴呼叫該函式,用分治法尋找最大子陣列
info find_maximum_subarray(int a, int low, int
high)
}int
main();
info max_subarray = find_maximum_subarray(a, 0, 9
);
out<<"
左下標為:
"右下標為:
"子陣列大小為:
"return0;
}
演算法二(線性複雜度):
對於陣列a[1...n],從左到右遍歷陣列,記錄目前為止處理過的最大子陣列,直到遍歷完整個陣列,具體思路如下:
對於1<=j<=n,記錄a[1...j]的最大子陣列和最大a[i...j]的值,那麼a[1...j+1]的最大子陣列為下面3種情況之一,取最優即可:
1)a[1...j]的最大子陣列
2)a[i...j]+a[j+1]
3)a[j+1]
具體c++程式實現:
#include#define len 10using
namespace
std;
void find_max_array(int a,int low,int
high)
else
if(sum1}
cout
<<"
左下標為:
"cout
<<"
右下標為:
"cout
<<"
子陣列和為:
"}int
main();
find_max_array(a,
0,len-1
);
return0;
}
總結:分治方法可能會得到演算法複雜度低於暴力求解的演算法,對於某些問題,分治策略雖然能給出較優演算法,但不使用該策略甚至可以能做得更好,該問題就是很好的例子。
最大子陣列問題
顧名思義,最大子陣列問題是求乙個陣列array中 和最大的非空連續子陣列 這樣的連續子陣列我們叫做最大子陣列,它的應用也有 很多,比如說找出時間序列中兩個時間節點使得這兩個時間節點對應的值的落差最大,如下圖 對於這類問題,通過求原始時間序列的一階差分得到序列array,此時求得array的最大子陣列...
最大子陣列問題
include include include typedef struct num num extern void displayarray const int a,const int n 顯示陣列元素值 extern void buildarray int a,const int n 陣列元素賦...
最大子陣列問題
每週堅持搞三種演算法問題,介紹一下最大子陣列問題 演算法思路 分治策略求解,將問題不斷分為更小的問題,進而求解 問題描述 求陣列中相連著的數 相加值最大,例如 輸出最大為2 3 4 21 22 define crt secure no warnigns include include include...