最大子陣列問題(三種方式,java實現)
阿新 • • 發佈:2019-02-04
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
3.遞迴,時間複雜度為n*logn/** * 暴力求解 : 時間複雜度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; }
/** * 遞迴演算法 : 將陣列一分為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}; }