最大子数组问题

  1. 算法描述
    求解数组中最大子数组的位置,和归并排序类似,也是使用分治法,最大字数组的位置要么出现在原数组的左半部分,要么出现在原数组的右半部分,要么一部分在左半部分,一部分在右半部分。
  2. 算法实现
package sxd.learn.algorithms;

public class Find_Max_SubArray {
    public static void main(String[] args){
        //iArray[7..10]为最大字数组
        int[] iArray = {13, -3, -25, 20, -3,
                        -16, -23, 18, 20, -7,
                        12, -5, -22, 15, -4,
                        7};
         IndexAndSum result = findMaxSubarray(iArray, 0, iArray.length -1);
         System.out.println("iArray[" + result.lowIndex + ".."+ result.highIndex + "]"
                 + "\t" + "sum:" + result.sum);
    }

    /**
     * @param iArray
     * @return 最大子数组下标及其和的对象
     */
    public static IndexAndSum findMaxSubarray(int[] iArray, int low, int high){
        if (low == high) {
            return new IndexAndSum(low, high, iArray[low]);
        }else{
            int mid = (low + high) / 2;
            IndexAndSum leftObject = findMaxSubarray(iArray, low, mid);
            IndexAndSum rightObject = findMaxSubarray(iArray, mid + 1, high);
            IndexAndSum crossObject = findMaxCrossingSubarray(iArray, low, mid, high);

            if (leftObject.sum > rightObject.sum && leftObject.sum > crossObject.sum) {
                return leftObject;
            }else if(rightObject.sum > leftObject.sum && rightObject.sum > crossObject.sum){
                return rightObject;
            }else{
                return crossObject;
            }
        }
    }

    /**
     * @param iArray
     * @return  下标元组划定跨越中点的最大字数组的边界和最大字数组中值的和对象
     */
    public static IndexAndSum findMaxCrossingSubarray(int[] iArray, int low, int mid, int high){
        int left_sum = Integer.MIN_VALUE;
        int right_sum = Integer.MIN_VALUE;
        int max_left = 0;
        int max_right = 0;

        int sum = 0;
        for(int i = mid; i >= low; i--){
            sum += iArray[i];
            if(sum > left_sum){
                left_sum = sum;
                max_left = i;
            }
        }

        sum = 0;
        for(int j = mid + 1; j<= high; j++){
            sum += iArray[j];
            if(sum > right_sum){
                right_sum = sum;
                max_right = j;
            }
        }

        return new IndexAndSum(max_left, max_right, left_sum + right_sum);
    }


    private static class IndexAndSum{
        public int lowIndex;
        public int highIndex;
        public int sum;

        public IndexAndSum(int lowIndex, int highIndex, int sum) {
            this.lowIndex = lowIndex;
            this.highIndex = highIndex;
            this.sum = sum;
        }   
    }
}
  1. 算法分析
    最大子数组问题不是一个典型的分治问题,是由于findMaxCrossingSubarray这个过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值