1.所謂最大子串行問題,就是希望在給定的陣列中,找出一串子串行,使得子串行的和最大。這個題目必須在字串裡存在負數,才有意義,否則直接取整個字串便是答案。
13-3
-2520
-316
-2318
20-7
12-5
-2215-47
如上例子,塗色部分便是最大子串行,和為43;
這道題這邊有三種思路。暴力破解就不在累贅,本節重點要記錄的是分治法,另一種巧法在文後也會介紹。
法一:分治法
分治法的思想便是將大問題轉化成小問題,迴圈往復直到問題規模小到可以直接求解。求a[low:high]的最大子串行,用分治法的思路便是:將a[low:mid]和a[mid+1:high]的最大子串行分別找出,取較大的那乙個即可(此處將大規模資料轉化為較小規模);然而本題還隱含一種情況,就是解包含在兩個子陣列裡的時候,上一方法是沒法找到的,所以這個單獨解決,好在這種解因為一定包含含a[low:mid]的最後乙個元素和a[mid+1:high]的第乙個元素,有了這個特徵便可以直接求解。詳細看**:
1/**2
* 求解最大子陣列問題
3* 分治4*
@author
yige5*
6*/78
9/**
10* 該類用於儲存結果,即子串行的首元素下標,尾元素下標,以及子串行的和
11*
@author
yige12*
13*/
1415
class
result
262728}
2930
public
class
maxsubarray 57}
58 sum=0;
5960 r=mid+1;
61for(int i=mid+1;i<=high;i++)67}
68return
new result(l,r,leftsum+rightsum);69}
7071
72/**
73* 分治法的框架,遞迴求解
74*
@param
array
75*
@param
low76
* @param
high
77*
@return
78*/
79static result findmaxsubarray(int array,int low,int
high)else
if(low95return
null;96
}9798public
static
void
main(string args)
112113 result result=findmaxsubarray(data, 0, n-1);
114115 system.out.println(result.left+" "+result.right+" "+result.sum);
116}
117118
}119
120 }
1public
class
maxsubarray2
1819
//result result=new result(0,0,0);
2021
/**22
* 思路主要在下面
23*/
2425
/**26
* 定義儲存最大子串行下標和總和的元素
27*/
28int maxleft=0;
29int maxright=0;
30int max=integer.min_value;
3132
/*33
* 定義當前關心的序列下標和元素(一旦當前序列和小於0,當前便不可能包含在要求的序列裡,從下乙個元素繼續找)
34*/
35int left=0;
36int right=0;
37int sum=0;
3839
//result maxresult=new result(0,0,integer.min_value);
4041
for(int i=0;i)else
if(sum<0)52}
5354 system.out.println(maxleft+" "+maxright+" "+sum);55}
5657 }
求最大子串行問題
輸入乙個整形陣列,陣列有正數也有負數,陣列中乙個或連續的多個整數組成乙個子陣列,求所有子陣列的和的最大值。時間複雜度為o n 剛開始想到的是暴力法,用三個迴圈,但是太費時了。之後想到如果一段子陣列的和為0或者小於0,那肯定不會有這段陣列。用動態規劃聽簡單,就是剛開始自己沒想全。用issum記錄當前子...
求最大子串行
1.暴力求解,時間複雜度為n 3 int maxsubarray int a int n return maxsum 2.分治法 將陣列從中間分開,那麼最大子陣列要麼完全再左半邊陣列,要麼完全在右半邊陣列,要麼跨立在分界點上。完全在左陣列 右陣列遞迴解決。跨立在分界點上 實際上是左陣列的最大字尾和右...
求序列的最大子串行
看 程式設計珠璣 一書,講解求序列的最大子串行。問題 給定乙個實數序列x1,x2,xn 不必是正數 尋找乙個連續的子串行xi,x i 1 xj,使得其數值之和在所有連續子串行數值之和中是最大的。演算法1思路 比較所有連續序列數值的和,找到最大的。1.maxsofar 0 2.for i 0,n 3....