描述
输入一个长度为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