Leetcode 5182. 刪除一次得到子數組最大和

今天參加了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

題目分析

題目中提到:可以從子數組中選擇是否要刪除一個元素,因此在遍歷到數組每一個元素的時候,都要比較從第一個元素到該元素爲止,刪除元素或者不刪除元素的最大連續子數組和。

  1. 不刪除元素的最大連續子數組和就是上面提到的經典題目,記爲sum_i_0
  2. 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

可能上面描述的也不是很清楚,大家有什麼疑問可以在評論區評論進行討論

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章