题目如下图所示:
链接地址:https://leetcode.com/problems/maximum-subarray/
暴力方法如下:
public static MaximumSubarrayInfo violence_maximumSubarray( int[] arr ) {
MaximumSubarrayInfo maximumSubarrayInfo = new MaximumSubarrayInfo();
int maxSum = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
int sum = 0;
int j = i;
while ( j < arr.length ) {
sum += arr[j];
if ( sum > maxSum ) {
maximumSubarrayInfo.setLeftIndex(i);
maximumSubarrayInfo.setRightIndex(j);
maxSum = sum;
}
j++;
}
}
maximumSubarrayInfo.setSum(maxSum);
return maximumSubarrayInfo;
}
所需时间复杂度为O(n^2),不能通过LeetCode上的测试。
下面为线性时间复杂度O(n)的代码:
public static int maxSubArray( int[] arr ) {
int maxSum = arr[0];
int sum = arr[0];
for (int i = 1; i < arr.length; i++) {
if ( sum < 0 )
sum = 0;
sum += arr[i];
maxSum = Math.max(sum, maxSum);
}
return maxSum;
}
下面为基于分治思想的代码如下:
package hanxl.insist.fourchapter;
public class MaximumSubarray {
public static void main(String[] args) {
int[] arr = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 };
MaximumSubarrayInfo maximumSubarray = findMaximumSubarray(arr, 0, arr.length);
System.out.println("左下标:" + maximumSubarray.getLeftIndex());
System.out.println("右下标:" + maximumSubarray.getRightIndex());
System.out.println("最大子数组和:" + maximumSubarray.getSum());
}
public static MaximumSubarrayInfo findMaximumSubarray(int[] arr, int lo, int hi) {
if ( lo >= hi - 1 )
return new MaximumSubarrayInfo(lo, lo, arr[lo]); // base case
int mi = ( lo + hi ) / 2;
MaximumSubarrayInfo leftMaximumSubarray = findMaximumSubarray(arr, lo, mi);
MaximumSubarrayInfo rightMaximumSubarray = findMaximumSubarray(arr, mi, hi);
MaximumSubarrayInfo crossingMaximumSubarray = findMaximunCrossingSubarray(arr, lo, mi, hi);
int leftSum = leftMaximumSubarray.getSum();
int rightSum = rightMaximumSubarray.getSum();
int crossingSum = crossingMaximumSubarray.getSum();
if ( leftSum > rightSum && leftSum > crossingSum )
return leftMaximumSubarray;
else if ( rightSum > leftSum && rightSum > crossingSum )
return rightMaximumSubarray;
else
return crossingMaximumSubarray;
}
public static MaximumSubarrayInfo findMaximunCrossingSubarray(int[] arr, int lo, int mi, int hi) {
MaximumSubarrayInfo maximumSubarrayInfo = new MaximumSubarrayInfo();
int leftSum = Integer.MIN_VALUE;
int sum = 0;
for (int i = mi - 1; i >= lo; i--) {
sum += arr[i];
if ( sum > leftSum ) {
leftSum = sum;
maximumSubarrayInfo.setLeftIndex(i);
}
}
int rightSum = Integer.MIN_VALUE;
sum = 0;
for (int i = mi; i < hi; i++) {
sum += arr[i];
if ( sum > rightSum ) {
rightSum = sum;
maximumSubarrayInfo.setRightIndex(i);
}
}
maximumSubarrayInfo.setSum(leftSum + rightSum);
return maximumSubarrayInfo;
}
/**
* 封装最大子数组的一些信息
* 包括最大子数组的左下标,右下标以及最大子数组的和。
*/
static class MaximumSubarrayInfo {
private int leftIndex;
private int rightIndex;
private int sum;
public MaximumSubarrayInfo() {}
public MaximumSubarrayInfo(int leftIndex, int rightIndex, int sum) {
this.leftIndex = leftIndex;
this.rightIndex = rightIndex;
this.sum = sum;
}
public int getLeftIndex() {
return leftIndex;
}
public void setLeftIndex(int leftIndex) {
this.leftIndex = leftIndex;
}
public int getRightIndex() {
return rightIndex;
}
public void setRightIndex(int rightIndex) {
this.rightIndex = rightIndex;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
}
}