import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class MaxSumOfSubArray {
@Test
public void test() throws IOException{
//int a[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
String s = MyFileUtil.read("src/test/java/lily/utils/arrays.txt");
System.out.println(s);
String[] ss = s.split(",");
System.out.println(ss.length);
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<ss.length;i++){
list.add(Integer.parseInt(ss[i]));
}
//List<Integer> list = Arrays.asList(13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7);
SubArray max = divideConqueMethod(list);
System.out.println(list.subList(max.maxLeft, max.maxRight+1));
System.out.println(max.maxSum);
max = linearMethod(list);
System.out.println(list.subList(max.maxLeft, max.maxRight+1));
System.out.println(max.maxSum);
}
/**
* 分治法
* @param list
* @return
*/
public SubArray divideConqueMethod(List<Integer> list){
if(list==null || list.size()==0){
return null;
}
return divideConqueMethod(list,0,list.size()-1);
}
public SubArray divideConqueMethod(List<Integer> list,int left, int right){
if(left==right){
return new SubArray(left,left,list.get(left));
}else{
int mid = (left+right)/2;
SubArray leftMaxArray = divideConqueMethod(list, left, mid);
SubArray rightMaxArray = divideConqueMethod(list, mid+1, right);
SubArray midMaxArray = getMaxArray(list,left,mid,right);
if(leftMaxArray.maxSum>=rightMaxArray.maxSum && leftMaxArray.maxSum>=midMaxArray.maxSum){
return leftMaxArray;
}
if(rightMaxArray.maxSum>=leftMaxArray.maxSum && rightMaxArray.maxSum>=midMaxArray.maxSum){
return rightMaxArray;
}
return midMaxArray;
}
}
private SubArray getMaxArray(List<Integer> list, int left, int mid, int right) {
int leftMax=Integer.MIN_VALUE,rightMax=Integer.MIN_VALUE;
int leftMaxPosition=mid,rightMaxPosition=mid;
int leftSum=0,rightSum=0;
for(int i=mid; i>=left;i--){
leftSum += list.get(i);
if(leftSum>leftMax){
leftMaxPosition=i;
leftMax =leftSum;
}
}
for(int j=mid+1;j<=right;j++){
rightSum += list.get(j);
if(rightSum>rightMax){
rightMaxPosition=j;
rightMax=rightSum;
}
}
return new SubArray(leftMaxPosition, rightMaxPosition, rightMax+leftMax);
}
class SubArray{
public int maxLeft;
public int maxRight;
public int maxSum;
public SubArray(int maxLeft, int maxRight, int maxSum){
this.maxLeft = maxLeft;
this.maxRight = maxRight;
this.maxSum = maxSum;
}
}
/**
* 线性算法
*/
public SubArray linearMethod(List<Integer> list){
int maxLeft=0,maxRight=0;
int maxSum=list.get(0);
for(int i=1;i<list.size();i++){
int tempMaxLeft=i;
int tempMaxSum=Integer.MIN_VALUE;
int tempSum=0;
for(int j=i;j>=0;j--){
tempSum+=list.get(j);
if(tempSum>tempMaxSum){
tempMaxSum=tempSum;
tempMaxLeft=j;
}
}
if(tempMaxSum>maxSum){
maxSum=tempMaxSum;
maxLeft=tempMaxLeft;
maxRight=i;
}
}
return new SubArray(maxLeft, maxRight, maxSum);
}
}
可稍加修改,使用https://leetcode.com/problems/maximum-subarray/进行验证
使用分治法时,通过;使用线性方法时,超时了,证明当list的size较大时,分治法的效率更高