欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

分治策略---求最大子数组

程序员文章站 2022-07-02 13:39:15
只有当数组中包含负数时,最大子数组问题才有意义。如果所有元素都是非负的,最大子数组问题没有任何意义,因为整个数组和肯定是最大的 ......

只有当数组中包含负数时,最大子数组问题才有意义。如果所有元素都是非负的,最大子数组问题没有任何意义,因为整个数组和肯定是最大的

 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 }