1588. 所有奇数长度子数组的和
题目描述
给你一个正整数数组 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 。
示例 3:
输入:arr = [10,11,12] 输出:66
提示:
1 <= arr.length <= 100
1 <= arr[i] <= 1000
进阶:
你可以设计一个 O(n) 时间复杂度的算法解决此问题吗?
解法
方法一:动态规划
我们定义两个长度为 \(n\) 的数组 \(f\) 和 \(g\),其中 \(f[i]\) 表示以 \(\textit{arr}[i]\) 结尾的长度为奇数的子数组的和,而 \(g[i]\) 表示以 \(\textit{arr}[i]\) 结尾的长度为偶数的子数组的和。初始时 \(f[0] = \textit{arr}[0]\),而 \(g[0] = 0\)。答案即为 \(\sum_{i=0}^{n-1} f[i]\)。
当 \(i > 0\) 时,考虑 \(f[i]\) 和 \(g[i]\) 如何进行状态转移:
对于状态 \(f[i]\),元素 \(\textit{arr}[i]\) 可以与前面的 \(g[i-1]\) 组成一个长度为奇数的子数组,一共可以组成的子数组个数为 \((i / 2) + 1\) 个,因此 \(f[i] = g[i-1] + \textit{arr}[i] \times ((i / 2) + 1)\)。
对于状态 \(g[i]\),当 \(i = 0\) 时,没有长度为偶数的子数组,因此 \(g[0] = 0\);当 \(i > 0\) 时,元素 \(\textit{arr}[i]\) 可以与前面的 \(f[i-1]\) 组成一个长度为偶数的子数组,一共可以组成的子数组个数为 \((i + 1) / 2\) 个,因此 \(g[i] = f[i-1] + \textit{arr}[i] \times ((i + 1) / 2)\)。
最终答案即为 \(\sum_{i=0}^{n-1} f[i]\)。
时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为数组 \(\textit{arr}\) 的长度。
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
方法二:动态规划(空间优化)
我们注意到,状态 \(f[i]\) 和 \(g[i]\) 的值只与 \(f[i - 1]\) 和 \(g[i - 1]\) 有关,因此我们可以使用两个变量 \(f\) 和 \(g\) 分别记录 \(f[i - 1]\) 和 \(g[i - 1]\) 的值,从而优化空间复杂度。
时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)。
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|