今天參加了LeetCode第153場周賽,其中第三題和一道經典題目——連續子數組的最大和很像。
我們這道題目的解法和之前這道經典題目的思路有些關係,連續子數組的最大和的解法見鏈接
題目描述
給你一個整數數組,返回它的某個 非空 子數組(連續元素)在執行一次可選的刪除操作後,所能得到的最大元素總和。
換句話說,你可以從原數組中選出一個子數組,並可以決定要不要從中刪除一個元素(只能刪一次哦),(刪除後)子數組中至少應當有一個元素,然後該子數組(剩下)的元素總和是所有子數組之中最大的。
注意,刪除一個元素後,子數組 不能爲空。
請看示例:
示例 1:
輸入: arr = [1,-2,0,3]
輸出: 4
解釋: 我們可以選出 [1, -2, 0, 3],然後刪掉 -2,這樣得到 [1, 0, 3],和最大。
示例 2:
輸入: arr = [1,-2,-2,3]
輸出: 3
解釋: 我們直接選出 [3],這就是最大和。
示例 3:
輸入: arr = [-1,-1,-1,-1]
輸出: -1
解釋: 最後得到的子數組不能爲空,所以我們不能選擇 [-1] 並從中刪去 -1 來得到 0。
我們應該直接選擇 [-1],或者選擇 [-1, -1] 再從中刪去一個 -1。
提示:
1 <= arr.length <= 10^5
-10^4 <= arr[i] <= 10^4
題目分析
題目中提到:可以從子數組中選擇是否要刪除一個元素,因此在遍歷到數組每一個元素的時候,都要比較從第一個元素到該元素爲止,刪除元素或者不刪除元素的最大連續子數組和。
- 不刪除元素的最大連續子數組和就是上面提到的經典題目,記爲
sum_i_0
- OK,那麼我們在遍歷到每一個元素的時候,對應的刪除元素的最大連續子數組和記爲
sum_i_1
,這個值應該怎麼求,這裏要用到動態規劃,沒錯又是動態規劃,那麼這個值的求法就肯定和上一步的連續子數組和有關係,比如我們遍歷到第i
個元素,那麼當前元素是arr[i]
,這時候的情況分兩種:刪除arr[i]
和保留arr[i]
。如果刪除arr[i]
,那麼要加上i-1
的不刪除元素的最大連續子數組和sum_(i-1)_0
,即0 + sum_(i-1)_0
;如果不刪除arr[i]
,那麼要加上i-1
的刪除元素的最大連續子數組和sum_(i-1)_1
。(總之就是,arr[i]
不刪除,前面就要刪除一個,arr[i]
刪除了,前面就不要刪除元素了)
代碼
代碼來自LeetCode 用戶 Rui
我將他的代碼改成了python版本
class Solution:
def maximumSum(self, arr):
n = len(arr)
dp_i_0 = -1e4
dp_i_1 = -1e4
ans = -(1e5)
for i in range(0, n):
dp_i_1 = max(dp_i_1 + arr[i], dp_i_0) # 利用動態規劃求 最大連續子數組和(刪除元素)
dp_i_0 = max(dp_i_0 + arr[i], arr[i]) # 這一行就是求 最大連續子數組和(不刪除元素)
ans = max(ans, max(dp_i_0, dp_i_1))
return ans
可能上面描述的也不是很清楚,大家有什麼疑問可以在評論區評論進行討論