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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回溯法是一种常用于解决组合问题的算法,通过不断尝试寻找满足特定条件的解,并记录下已经尝试过的解,从而找到最优解。在求解最大数组和的问题中,可以使用回溯法来找到所有可能的数组,然后从中找出和最大数组。 具体实现时,可以使用递归的方式,从数组的第一个元素开始,判断当前元素是否加入数组中。如果加入,则递归考虑下一个元素;如果不加入,则直接递归考虑下一个元素。需要注意的是,每次递归需要记录当前数组的和,以及当前最大数组和。 下面是一个使用回溯法求解最大数组和的示例代码: ```c #include <stdio.h> int max_sum = 0; // 记录最大数组和 void backtrack(int array[], int start, int sum, int size) { if (start == size) { // 递归终止条件,到达数组末尾 if (sum > max_sum) { max_sum = sum; // 更新最大数组和 } return; } // 加入当前元素 backtrack(array, start + 1, sum + array[start], size); // 不加入当前元素 backtrack(array, start + 1, sum, size); } int main() { int array[] = {1, -2, 3, 10, -4, 7, 2, -5}; int size = sizeof(array) / sizeof(array[0]); backtrack(array, 0, 0, size); printf("最大数组和为:%d\n", max_sum); return 0; } ``` 以上代码中,通过回溯法遍历了数组中的所有数组,并更新最大数组和的值,最终输出结果为最大数组和为18。 需要注意的是,该算法的时间复杂度为O(2^n),因为遍历了所有可能的数组。在实际应用中,可以使用动态规划或分治法等更优化的算法来解决最大数组和的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值