题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?
python实现:
# -*- coding:utf-8 -*-
class Solution:
#法1:动态规划
def FindGreatestSumOfSubArray1(self, array):
# write code here
#dp[i]表示以array[i]为结尾的子数组(0, i)的最大和
#如果dp[i-1]>0, dp[i] = dp[i-1]+array[i]
#如果dp[i-1]<=0, dp[i] = array[i]
n = len(array)
if n==0:
return 0
dp = [0]*n
#初始化
dp[0] = array[0]
for i in range(1, n):
if dp[i-1]<=0:
dp[i] = array[i]
else:
dp[i] = dp[i-1] + array[i]
return max(dp)
#法2:分治
#参考:http://blog.csdn.net/a272846945/article/details/50822601
def FindGreatestSumOfSubArray(self, array):
n = len(array)
if n==0:
return 0
return self.devideAndConquer(array, 0, n-1)
def devideAndConquer(self, nums, low, high):
if low==high:
return nums[low]
mid = (low+high)/2
leftMaxSum = self.devideAndConquer(nums, low, mid)
rightMaxSum = self.devideAndConquer(nums, mid+1, high)
crossMaxSum = self.merge(nums, low, mid, high)
return max(leftMaxSum, rightMaxSum, crossMaxSum)
def merge(self, nums, low, mid, high):
continousLeftSum = nums[mid]
tmpLeftSum = nums[mid]
for i in range(mid-1, low-1, -1):
tmpLeftSum += nums[i]
continousLeftSum = max(continousLeftSum, tmpLeftSum)
continousRightSum = nums[mid+1]
tmpRightSum = nums[mid+1]
for i in range(mid+2, high+1):
tmpRightSum += nums[i]
continousRightSum = max(continousRightSum, tmpRightSum)
return continousLeftSum + continousRightSum