leetcode之Maximum Subarray

题目如下图所示:

这里写图片描述

链接地址: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;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值