1. 程式人生 > >最大連續子陣列

最大連續子陣列

題目: 給定一個數組 A[0,1..... ,n-1],求A的連續子陣列,使得該子陣列的和最大。

例如:

  陣列: 1,-2,3,10,-4,7,2,-5

  最大子陣列: 3,10,-4,7,2

 

解法1:(暴力code)

  

 1 public class MaxSubArray {
 2     
 3     public static int MaxArray(int [] arr,int n)
 4     {
 5         int maxSum = arr[0];
 6         int currSum;
 7         for
(int i = 0;i<n;i++) 8 { 9 10 for(int j = i ;j<n ;j++) 11 { 12 currSum = 0; 13 for(int k = i;k<j;k++) 14 { 15 currSum+=arr[k]; 16 } 17 if(currSum>maxSum)
18 { 19 maxSum = currSum; 20 } 21 22 } 23 } 24 25 return maxSum; 26 } 27 public static void main(String[] args) { 28 29 int [] array = {1,-2,3,10,-4,7,2,-5}; 30
int maxArray = MaxArray(array, array.length); 31 System.out.println(maxArray); 32 } 33 34 }

解法2.分治法

  將陣列從中間分開,那麼最大子陣列要麼完全在左半邊陣列,要麼完全在右半邊陣列,要麼跨立在分界點上。

  完全在左陣列、右陣列遞迴解決。

  跨立在分界點上:實際上是左陣列的最大字尾和右陣列的最大字首的和。因此,從分界點向前掃,向後掃即可

 1 //解法2.分治法求解
 2     public static int MaxAddSub(int [] arr,int from ,int to)
 3     {
 4         //定義遞迴的出口
 5         if(to == from )
 6             return arr[from];
 7         //求陣列的中間位置
 8         int middle = (from + to)/2;
 9         //左邊最大的子陣列的和
10         int m1 = MaxAddSub(arr, from, middle);
11         //右邊最大子陣列的和
12         int m2 = MaxAddSub(arr,middle+1,to);
13         
14         //這種情況 就是最大的子序列在中間的情況
15         int i ,left = arr[middle],now = arr[middle];
16         for(i = middle -1;i>=from;--i)
17         {
18             now += arr[i];
19             //left中只保留向左 去的最大的自序列的情況
20             left = Math.max(now,left);
21         }
22         
23         
24         //向右的情況是從middle+1 開始的防止重複計算中間值的情況
25         int right = arr[middle+1];
26         now = arr[middle+1];
27         for( i = middle+2;i<= to;++i)
28         {
29             now += arr[i];
30             // right只保留向右最大的情況
31             right = Math.max(now,right);
32         }
33         //m3 是向左最大的情況加上向右的最大情況
34         int m3 = left+right; 
35         
36         //最中返回這個區間中三中情況中值最大的情況
37         return Math.max(Math.max(m1,m2),m3);
38         
39     }