分治策略---求最大子数组
Posted joe-666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治策略---求最大子数组相关的知识,希望对你有一定的参考价值。
只有当数组中包含负数时,最大子数组问题才有意义。如果所有元素都是非负的,最大子数组问题没有任何意义,因为整个数组和肯定是最大的
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 }
以上是关于分治策略---求最大子数组的主要内容,如果未能解决你的问题,请参考以下文章