【算法学习笔记】- 剑指OFFER 42题 连续子数组的最大和

描述
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
数据范围:
1 <= n <= 10^51<=n<=10
5

-100 <= a[i] <= 100−100<=a[i]<=100

要求:时间复杂度为 O(n)O(n),空间复杂度为 O(n)O(n)
进阶:时间复杂度为 O(n)O(n),空间复杂度为 O(1)O(1)

在这里插入图片描述
参考:
https://blog.nowcoder.net/n/b49b05b1b4d34f40ab2e9e72329ac72a

方法一

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        # size = len(array)
        temp = 0
        res = array[0]
        # 题目要求求连续子数组的最大和,下面这段代码只是求出该数组元素最大和,并不是它的连续子数组
        """
        for k in array:
            if k < 0:
                temp += 0
            else:
                temp += k 
            # res = max(res , temp)
        return temp
        """
        for k in array:
            if temp + k < 0 :
                temp = 0
            else:
                temp += k
            res = max(res, temp)
            # 上面代码的思路:
            # 当k = -2时 temp = -1,这个时候 res肯定还是取上一次遍历的值
            # 继续遍历到-5时 temp = 13,上一次res = 18,这个时候因为-5已经是
            # 数组的最后的值,所以res 的最大值是18
        if temp != 0:
            return res
        else:
            return max(array) # 如果temp==0,证明数组里的元素都是负数,那就只取数组的最大值就好了

方法二:

动态规划:
状态定义:dp[i]表示以i结尾的连续子数组的最大和。所以最终要求dp[n-1]
状态转移方程:dp[i] = max(array[i], dp[i-1]+array[i])
解释:如果当前元素为整数,并且dp[i-1]为负数,那么当然结果就是只选当前元素
技巧:这里为了统一代码的书写,定义dp[i]表示前i个元素的连续子数组的最大和,结尾元素为array[i-1]

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        size = len(array) + 1
        res = array[0]
        dp = [0]*size
        for i in range(1, size):
            # dp[i] = max(array[i], dp[i-1] + array[i]) # IndexError: list index out of range
            dp[i] = max(array[i-1], dp[i-1] + array[i-1])
            res = max(res, dp[i])
        return res

猜你喜欢

转载自blog.csdn.net/jackhh1/article/details/121312017