連續子陣列最大和O(n)兩種解法:雙指標 動態規劃
阿新 • • 發佈:2018-11-30
題目描述
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),因此第二種方法優