53. 最大子序和

题目

53. 最大子序和_第1张图片

解析

参考leetcode-最大子序和(四种)

第一种解法——暴力枚举法 O(N^3)

从左往右依次找出所有的子序列并计算其每个子序列的和,最后返回最大的

    //暴力破解O(N^3)
    public int maxSubArray(int[] nums) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {// 子序列左端点
            for (int j = i; j < nums.length; j++) {// 子序列右端点
                int sum = 0;
                for (int k = i; k <= j; k++) {//暴力计算
                    sum += nums[k];
                }
                if (max < sum) {
                    max = sum;
                }
            }
        }
        return max;
    }

第二种解法——改进的暴力枚举法 O(N^2)

在第一种解法的过程中,事实上我们是在找到子序列之后再进行计算的,其实完全可以边找边计算,这样就可以减少一层循环了

    //暴力破解改进O(N^2)
    public int maxSubArray(int[] nums) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {// 子序列左端点
            int sum = 0;
            for (int j = i; j < nums.length; j++) {// 子序列右端点
                sum += nums[j];//这一步相当于每次根据前一次的序列来计算新的序列和
                if (max < sum)
                    max = sum;
            }
        }
        return max;
    }

第三种——扫描法 O(N)

基本思想:当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的序列和是一个负数,那么下一个数无论正负加上该序列都会减小,所以这个序列和应当在接下来的累加中被抛弃

    //扫描法
    /**
     * curSum 表示当前执行过程中的和,
     * 如果当前序列执行过程的和小于0,说明再往后加只会减小当前序列和,此时curSum应该转变为nums[i],然后开始计算新的序列和
     */
    public int maxSubArray(int[] nums) {
        int curSum = nums[0];
        int max = nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (curSum < 0)
                curSum = nums[i];
            else
                curSum += nums[i];
            if (curSum > max)
                max = curSum;
        }
        return max;
    }

你可能感兴趣的:(53. 最大子序和)