算法导论——最大子数组和

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较大时,分治法的效率更高

点赞