1588 所有奇數長度子陣列的和(字首和)

smalllxp發表於2020-10-01

1. 問題描述:

給你一個正整數陣列 arr ,請你計算所有可能的奇數長度子陣列的和。子陣列 定義為原陣列中的一個連續子序列。請你返回 arr 中 所有奇數長度子陣列的和 。

示例 1:

輸入:arr = [1,4,2,5,3]
輸出:58
解釋:所有奇數長度子陣列和它們的和為:
[1] = 1
[4] = 4
[2] = 2
[5] = 5
[3] = 3
[1,4,2] = 7
[4,2,5] = 11
[2,5,3] = 10
[1,4,2,5,3] = 15
我們將所有值求和得到 1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58

示例 2:

輸入:arr = [1,2]
輸出:3
解釋:總共只有 2 個長度為奇數的子陣列,[1] 和 [2]。它們的和為 3 

示例 2:

輸入:arr = [10,11,12]
輸出:66

提示:

  • 1 <= arr.length <= 100
  • 1 <= arr[i] <= 1000

2. 思路分析:

① 分析題目可以知道我們是要求解出所有奇數長度的的子陣列的和,所以這裡涉及到一個範圍內的子陣列的和,所以比較容易想到的是字首和的解決方法,我們需要求解出從0到當前位置的字首和(當前位置的最大長度為陣列的長度 + 1),這樣我們就可以通過下標相減的方法來求解某個範圍的子陣列的和,因為是要求解出奇數長度的子陣列,所以我們想到使用兩層for迴圈來解決,第一層for迴圈表示的是子陣列的奇數長度(步長為2),第二層for迴圈是從當前位置開始長度為k的子陣列的範圍(k為當前的子陣列的長度),這樣我們可以通過之前得到的字首和陣列通過下標的方式相減就可以得到長度為奇數的子陣列的和了

② 而且對於陣列邊界的確定問題最好的解決方法是寫出具體的例子進行簡單的分析, 進行debug除錯就可以得到具體的範圍

3. 程式碼如下:

from typing import List


class Solution:
    def sumOddLengthSubarrays(self, arr: List[int]) -> int:
        presum = [0] * (len(arr) + 1)
        for i in range(1, len(arr) + 1):
            presum[i] = presum[i - 1] + arr[i - 1]
        res = 0
        n = len(arr)
        # 步長為2,所以得到的奇數長度序列為1,3,5...
        for length in range(1, n + 1, 2):
            for i in range(length, n + 1):
                res += (presum[i] - presum[i - length])
        return res

 

相關文章