最大子数组问题(三种方式,java实现)

来源:互联网 发布:保险公司业务数据分析 编辑:程序博客网 时间:2024/05/29 10:30

1.动态规划,时间复杂度为n

/** * 动态规划 : 时间复杂度n * @param arr * @return */public static Integer maxSubArray(Integer[] arr) {Integer max_sum = Integer.MIN_VALUE;Integer min_index = 0;Integer max_index = 0;int sum = 0;for (int i = 0; i < arr.length; i++) {if(sum < 0) {sum = 0;min_index = i;}sum = sum + arr[i];if(max_sum < sum) {max_sum = sum;max_index = i;}}System.out.print(min_index + " " + max_index + " ");return max_sum;}

2.暴力求解,时间复杂度为n^2

/** * 暴力求解 : 时间复杂度n^2 * @param arr * @return */public static Integer maxSubArray(Integer[] arr) {Integer max_sum = Integer.MIN_VALUE;Integer min_index = 0;Integer max_index = 0;for (int i = 0; i < arr.length; i++) {int sum = 0;for (int j = i; j < arr.length; j++) {sum += arr[j];if(sum > max_sum) {min_index = i;max_index = j;max_sum = sum;}}}System.out.print(min_index + " " + max_index + " ");return max_sum;}
3.递归,时间复杂度为n*logn

/** * 递归算法 : 将数组一分为2,最大子数组要么在左边部分;要么在右边部分;要么穿过中点,最边一部分+右边一部分。 时间复杂度:n*logn * @return 结果数组:起点,终点,最大值 */public static Integer[] find_maximum_subarray(Integer[] A, int low, int high) {if(high == low) {return new Integer[]{low, high, A[low]};} else {int mid = (low + high) / 2;Integer[] l_maximum_subarray = find_maximum_subarray(A, low, mid);Integer[] r_maximum_subarray = find_maximum_subarray(A, mid + 1, high);Integer[] crossing_subarray = find_max_crossing_subarray(A, low, mid, high);if(l_maximum_subarray[2] >= r_maximum_subarray[2] && l_maximum_subarray[2] >= crossing_subarray[2]) {return l_maximum_subarray;} else if(r_maximum_subarray[2] >= l_maximum_subarray[2] && r_maximum_subarray[2] >= crossing_subarray[2]) {return r_maximum_subarray;} else {return crossing_subarray;}}}public static Integer[] find_max_crossing_subarray(Integer[] A, int low, int mid, int high) {int left_sum = Integer.MIN_VALUE;int sum = 0;int max_left = 0;for (int i = mid; i >= low; i--) {sum = sum + A[i];if(sum > left_sum) {left_sum = sum;max_left = i;}}int right_sum = Integer.MIN_VALUE;int max_right = 0;sum = 0;for (int j = mid + 1; j <= high; j++) {sum = sum + A[j];if(sum > right_sum) {right_sum = sum;max_right = j;}}return new Integer[]{max_left, max_right, left_sum + right_sum};}



1 0