1. 程式人生 > >分治策略---求最大子數組

分治策略---求最大子數組

msu sin system 相等 最大子數組 for urn out oid

只有當數組中包含負數時,最大子數組問題才有意義。如果所有元素都是非負的,最大子數組問題沒有任何意義,因為整個數組和肯定是最大的

 1 public class FindMaxSubArrayDemo {
 2     public static void main(String[] args) {
 3         int[] arr = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
 4         int[] result_arr = findMaximumSubarray(arr, 0, arr.length - 1);
5 for (int i = 0; i < result_arr.length; i++) { 6 System.out.println(result_arr[i]); 7 } 8 } 9 /* 10 最大數組問題:使用分治策略 11 分析:1.要將大數組劃分為兩個規模盡量相等的子數組,也就是找到大數組的中央位置mid, 12 2.求解兩個子數組A[low,mid]和A[mid+1,high] 13 3,那麽所求的最大數組A[i,j]就只用三種情況 14 * 第一種情況:完全位於A[low,mid],因此low <= i <= j <= mid;
15 * 第二種情況:完全位於A[mid+1,high],因此 mid+1 <= i <= j <= high; 16 * 第三種情況:跨越了中點,因此low <= i <= mid j <= high; 17 4.可以遞歸第一種和第二種情況的最大子數組問題,因為兩個子問題仍然是最大數組問題,只是規模更小 18 5.因此,只要尋找跨越中點的最大子數組 19 6.最後進行三者比較選取最大值的問題。 20 */ 21 public static int[] findMaxCrossingSubArray(int
[] arr, int low, int mid, int high) {//找出跨越中點最大子數組的方法 22 int left_sum = arr[low];//存儲左半部的和 23 int sum = 0; //存儲元素和,來分別與左右半部的和進行比較 24 int right_sum = arr[high]; //存取右半部的和 25 int max_left = 0; //存取最左邊的角標 26 int max_right = 0;//存取最右邊的角標 27 int[] result_arr = new int[3]; 28 for (int i = mid; i >= low; i--) { 29 sum = sum + arr[i]; 30 if (sum > left_sum) { 31 left_sum = sum; 32 max_left = i; 33 } 34 } 35 sum = 0; 36 for (int i = mid + 1; i <= high; i++) { 37 sum = sum + arr[i]; 38 if (sum > right_sum) { 39 right_sum = sum; 40 max_right = i; 41 } 42 } 43 result_arr[0] = max_left; 44 result_arr[1] = max_right; 45 result_arr[2] = left_sum + right_sum; 46 return result_arr; 47 } 48 49 public static int[] findMaximumSubarray(int[] arr, int low, int high) { 50 int[] result_arr = new int[3]; 51 if (high == low) { //base case: only one element 52 result_arr[0] = low; 53 result_arr[1] = high; 54 result_arr[2] = arr[low]; 55 return result_arr; 56 } else { 57 int mid = (low + high) / 2; 58 int[] left_result_arr = findMaximumSubarray(arr, low, mid); //第一種情況 59 int[] right_result_arr = findMaximumSubarray(arr, mid + 1, high); //第二種情況 60 int[] cross_result_arr = findMaxCrossingSubArray(arr, low, mid, high); //第三種情況 61 if (left_result_arr[2] >= right_result_arr[2] && left_result_arr[2] >= cross_result_arr[2]) { 62 return left_result_arr; 63 } else if (right_result_arr[2] >= left_result_arr[2] && right_result_arr[2] >= cross_result_arr[2]) { 64 return right_result_arr; 65 } else { 66 return cross_result_arr; 67 } 68 } 69 } 70 }

分治策略---求最大子數組