1. 程式人生 > >連續子陣列最大和O(n)兩種解法:雙指標 動態規劃

連續子陣列最大和O(n)兩種解法:雙指標 動態規劃

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


解法1 雙指標+動態規劃

採用一個指標指向最前面,一個指標指向最後面,兩個指標交錯移動,當移動一位發現這一位前面/後面的所有和為負數的時候,說明這兩個指標夾的陣列要比之前的陣列和更大,如果使用遞迴,達不到O(N)的時間複雜度,因為有很多重複計算,因此使用兩個陣列來儲存前向和後向遍歷的和

class Solution:
    def GetSum(self, array, start, end):
        sum = 0
        for i in range(start, end + 1):
            sum += array[i]
        return sum
    def EvaluateSum(self, array, index, subArraySum, flag):
        if index == 0 or index == len(array) - 1:
            return array[index]
else: if flag: return subArraySum[0][index - 1] + array[index] else: return subArraySum[1][index + 1] + array[index] def FindGreatestSumOfSubArray(self, array): # write code here flag = 1 subArraySum = [([0] *
len(array)) for i in range(2)] low, high = 0, len(array) - 1 i = low + 1 j = high - 1 subArraySum[0][0] = array[0] subArraySum[1][len(array) - 1] = array[len(array) - 1] while low < high: if low < high and flag: for i in range(low + 1, high + 1): subArraySum[0][i] = self.EvaluateSum(array, i, subArraySum, flag) if subArraySum[0][i - 1] < 0: low = i flag = 0 break elif low < high and not flag: for j in range(high - 1, low - 1, -1): subArraySum[1][j] = self.EvaluateSum(array, j, subArraySum, flag) if subArraySum[1][j + 1] < 0: high = j flag = 1 break if i == high or j == low: #跳出主迴圈,防止找不到更大的,low和high不改變一致迴圈 break return self.GetSum(array, low, high)

執行時間:25ms

佔用記憶體:5840k


解法2 用一個指標方法

當array[i]大於之前所有數字的和的時候,說明要丟棄前面所有的陣列,這個時候如果array[i]>全域性的最大值,那麼需要更新全域性的最大值,如果array[i]小於之前的和,那麼判斷這個和與全域性最大值的大小

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        if array == []:
            return 0
        if len(array) == 1:
            return array[0]
        maxSum = totalSum = array[0]
        #low = 0
        for i in range(1, len(array)):
            totalSum += array[i]
            print(i, array[i], totalSum, maxSum)
            if array[i] > totalSum:
                #low = i
                totalSum = array[i]
                if array[i] > maxSum:
                    maxSum = array[i]
            else:
                if totalSum > maxSum:
                    maxSum = totalSum
        return maxSum

執行時間:25ms

佔用記憶體:5728k


比較

兩種方法時間複雜度都是O(N),第一種解法程式碼量大,並且演算法複雜,空間複雜度為O(2N),因此第二種方法優