【剑指Offer】最大子数组的最大和Day2

题目描述

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).

示例1

输入

[1,-2,3,10,-4,7,2,-5]

返回值

18

说明

输入的数组为{1,-2,3,10,—4,7,2,一5},和最大的子数组为{3,10,一4,7,2},因此输出为该子数组的和 18。 

此题的意思是,所给数组的所有子集 求出和最大的值。

拿到这道题后我首先想到的是 使用双重for循环,将每个位置的和全部算出来,在求最大值

最后发现很麻烦,而且时间复杂度也不满足。

说来惭愧,学习了一学期算法课,典型的动态规划问题没有看出来。

这里简单说一下动态规划算法:类似与分治算法,将问题进行拆分,再通过递推或者递归解决,只保存最优解,前一问题的解会帮助后一问题的求解。

再来说这个问题:

求所有子集和的最大值

思路:将问题拆解,可以先求出数组前n-1项的最大子序列的和, 用arr[n-1]保存起来,再进行判断,如果它大于0,则arr[n]+arr[n-1] 因为是正数所以加上后肯定会增大,反之前n-1项的和为负数,则不值得继续计算,并置为0,arr[n]不变,从n位置继续计算。最后用max保存最大值即可

代码如下

 public int FindGreatestSumOfSubArray(int[] array) {
    
    
            int max = array[0]; //max 保存最大值
          for (int i = 1; i < array.length; i++){
    
     //遍历数组
              //array[i-1]保存到当前元素的子序列的最大和
              if (array[i-1] < 0){
    
    //如果小于0,则不值得相加置为0,从i位置重新开始
                  array[i-1] = 0;
              }
              //加起来
              array[i] += array[i-1];
             //再用max记录最大值
              max = Math.max(max,array[i]);
          }
           return max;
    
    }

大佬是这样写的,三目运算符还是很简便的

public int FindGreatestSumOfSubArray(int[] array) {
    
    
    int max = array[0];
    for (int i = 1; i < array.length; i++) {
    
    
        array[i] += array[i - 1] > 0 ? array[i - 1] : 0;
        max = Math.max(max, array[i]);
    }
    return max;
}

时间复杂度O(n)

空间复杂度O(1)

猜你喜欢

转载自blog.csdn.net/weixin_46078315/article/details/112382486