本文代码为Python,但思路都是通用的
题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
**简化:**有一串数组,求其中任意连续子串之和的最大值,子串长度至少为1。
解题思路和代码
本题题意很好理解,容易理解错子串必须是从0开始,但其实是数组的任意子串,并不规定起止。
首先想到的方法就是把所有子串都遍历一遍。
第一种【穷举法】:
class Solution:
def FindGreatestSumOfSubArray(self, array):
if not array:
return 0
# 记录最大和
maxsum = array[0]
for i in range(len(array)):
# 记录子串和
asum = 0
for j in range(i,len(array)):
asum += array[j]
if asum > maxsum:
maxsum = asum
return maxsum
对于以 array[i]
为起点的所有子串进行求和,判断是否大于最大的子串和 maxsum
,如果是则将当前子串和赋值给 maxsum
。
这个方法思想有些类似简单选择排序,时间复杂度也相当O(N^2)。
第二种方法:
假设有一个数组 array = [-2,-3,4,-1,-2,1,5,-3],我们用 maxsum[i] 来表示以元素array[i]结尾的最大连续子数组和。
我们可以发现以下结论:
maxsum[i] = max(maxsum[i-1]+array[i], array[i])
class Solution:
def FindGreatestSumOfSubArray(self, array):
if not array:
return 0
sumlist = [array[0]]
for i in range(1,len(array)):
sumlist.append(max(sumlist[i-1]+array[i],array[i]))
return max(sumlist)
这种方法的思考方向与第一种刚好相反,第一种是判断以 array[i]
为起点的所有子串,这种是判断以 array[i]
为终点的所有子串,并且可以借助上一个节点的最大字串和来判断当前节点的最大子串和。
很明显第二种方法要更优一些,时间复杂度是O(N)。