劍指offer:連續子數組的最大和

題目描述
HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同窗。今天測試組開完會後,他又發話了:在古老的一維模式識別中,經常須要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。可是,若是向量中包含負數,是否應該包含某個負數,並指望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。給一個數組,返回它的最大連續子序列的和,你會不會被他忽悠住?(子向量的長度至少是1)git

# -*- coding: utf-8 -*-
# @Time         : 2019-07-09 15:45
# @Author       : Jayce Wong
# @ProjectName  : job
# @FileName     : findGreatestSumofSubArray.py
# @Blog         : https://blog.51cto.com/jayce1111
# @Github       : https://github.com/SysuJayce

class Solution:
    """
    求連續子數組的最大和,其實就是說從給定數組中選擇一個子數組,使得子數組的和最大。

    解法0:
    最樸素的解法,就是遍歷全部可能的子數組,而後找到和最大的子數組。共有(1+n)n/2個子數組,而後求
    和的複雜度爲O(n),也就是這種解法的時間複雜度約爲O(n^3)

    解法1:
    維護兩個變量,分別記錄當前和、最大和,若是當前和大於最大和,那麼更新最大和。

    遍歷整個數組,若是加上上一個元素後當前和爲負數,那麼當前元素不能再與前面元素連起來,
    由於任何數加負數只會更小。因此當前元素須要做爲新的子數組的起點,置當前和爲當前元素的值

    解法2:
    動態規劃。
    dp[i]表示以array中第i個元素爲結尾的子數組的最大和
    dp[i] = array[i],當i=0或dp[i-1]<0
    dp[i] = array[i] + dp[i-1],當dp[i-1]>=0
    """
    def FindGreatestSumOfSubArray1(self, array):
        if not array:
            raise TypeError("Invalid input")

        curSum = 0
        greatestSum = -float('inf')
        for num in array:
            if curSum <= 0:
                curSum = num
            else:
                curSum += num
            greatestSum = max(curSum, greatestSum)

        return greatestSum

    def FindGreatestSumOfSubArray(self, array):
        if not array:
            raise TypeError("Invalid input")

        dp = [array[0]] * len(array)
        for i in range(1, len(array)):
            if dp[i - 1] < 0:
                dp[i] = array[i]
            else:
                dp[i] = array[i] + dp[i - 1]
        return max(dp)

def main():
    solution = Solution()
    nums = [6, -3, -2, 7, -15, 1, 2, 2]
    print(solution.FindGreatestSumOfSubArray(nums))

if __name__ == '__main__':
    main()
相關文章
相關標籤/搜索