@@ -80,11 +80,19 @@ tags:
8080
8181<!-- solution:start -->
8282
83- ### 方法一:枚举 + 前缀和
83+ ### 方法一:动态规划
8484
85- 我们可以枚举子数组的起点 $i$ 和终点 $j$ ,其中 $i \leq j$,维护每个子数组的和,然后判断子数组的长度是否为奇数,如果是,则将子数组的和加入答案 。
85+ 我们定义两个长度为 $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 ] $ 。
8686
87- 时间复杂度 $O(n^2)$,空间复杂度 $O(1)$。其中 $n$ 是数组的长度。
87+ 当 $i > 0$ 时,考虑 $f[ i] $ 和 $g[ i] $ 如何进行状态转移:
88+
89+ 对于状态 $f[ i] $,元素 $\textit{arr}[ i] $ 可以与前面的 $g[ i-1] $ 组成一个长度为奇数的子数组,一共可以组成的子数组个数为 $(i / 2) + 1$ 个,因此 $f[ i] = g[ i-1] + \textit{arr}[ i] \times ((i / 2) + 1)$。
90+
91+ 对于状态 $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)$。
92+
93+ 最终答案即为 $\sum_ {i=0}^{n-1} f[ i] $。
94+
95+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{arr}$ 的长度。
8896
8997<!-- tabs:start -->
9098
@@ -93,13 +101,14 @@ tags:
93101``` python
94102class Solution :
95103 def sumOddLengthSubarrays (self , arr : List[int ]) -> int :
96- ans, n = 0 , len (arr)
97- for i in range (n):
98- s = 0
99- for j in range (i, n):
100- s += arr[j]
101- if (j - i + 1 ) & 1 :
102- ans += s
104+ n = len (arr)
105+ f = [0 ] * n
106+ g = [0 ] * n
107+ ans = f[0 ] = arr[0 ]
108+ for i in range (1 , n):
109+ f[i] = g[i - 1 ] + arr[i] * (i // 2 + 1 )
110+ g[i] = f[i - 1 ] + arr[i] * ((i + 1 ) // 2 )
111+ ans += f[i]
103112 return ans
104113```
105114
@@ -109,15 +118,13 @@ class Solution:
109118class Solution {
110119 public int sumOddLengthSubarrays (int [] arr ) {
111120 int n = arr. length;
112- int ans = 0 ;
113- for (int i = 0 ; i < n; ++ i) {
114- int s = 0 ;
115- for (int j = i; j < n; ++ j) {
116- s += arr[j];
117- if ((j - i + 1 ) % 2 == 1 ) {
118- ans += s;
119- }
120- }
121+ int [] f = new int [n];
122+ int [] g = new int [n];
123+ int ans = f[0 ] = arr[0 ];
124+ for (int i = 1 ; i < n; ++ i) {
125+ f[i] = g[i - 1 ] + arr[i] * (i / 2 + 1 );
126+ g[i] = f[i - 1 ] + arr[i] * ((i + 1 ) / 2 );
127+ ans += f[i];
121128 }
122129 return ans;
123130 }
@@ -131,15 +138,13 @@ class Solution {
131138public:
132139 int sumOddLengthSubarrays(vector<int >& arr) {
133140 int n = arr.size();
134- int ans = 0;
135- for (int i = 0; i < n; ++i) {
136- int s = 0;
137- for (int j = i; j < n; ++j) {
138- s += arr[ j] ;
139- if ((j - i + 1) & 1) {
140- ans += s;
141- }
142- }
141+ vector<int > f(n, arr[ 0] );
142+ vector<int > g(n);
143+ int ans = f[ 0] ;
144+ for (int i = 1; i < n; ++i) {
145+ f[ i] = g[ i - 1] + arr[ i] * (i / 2 + 1);
146+ g[ i] = f[ i - 1] + arr[ i] * ((i + 1) / 2);
147+ ans += f[ i] ;
143148 }
144149 return ans;
145150 }
@@ -151,14 +156,14 @@ public:
151156```go
152157func sumOddLengthSubarrays(arr []int) (ans int) {
153158 n := len(arr)
154- for i := range arr {
155- s := 0
156- for j := i; j < n; j++ {
157- s += arr[j ]
158- if (j-i+1)%2 == 1 {
159- ans += s
160- }
161- }
159+ f := make([]int, n)
160+ g := make([]int, n)
161+ f[0] = arr[0]
162+ ans = f[0 ]
163+ for i := 1; i < n; i++ {
164+ f[i] = g[i-1] + arr[i]*(i/2+1)
165+ g[i] = f[i-1] + arr[i]*((i+1)/2)
166+ ans += f[i]
162167 }
163168 return
164169}
@@ -169,15 +174,13 @@ func sumOddLengthSubarrays(arr []int) (ans int) {
169174``` ts
170175function sumOddLengthSubarrays(arr : number []): number {
171176 const n = arr .length ;
172- let ans = 0 ;
173- for (let i = 0 ; i < n ; ++ i ) {
174- let s = 0 ;
175- for (let j = i ; j < n ; ++ j ) {
176- s += arr [j ];
177- if ((j - i + 1 ) % 2 === 1 ) {
178- ans += s ;
179- }
180- }
177+ const f: number [] = Array (n ).fill (arr [0 ]);
178+ const g: number [] = Array (n ).fill (0 );
179+ let ans = f [0 ];
180+ for (let i = 1 ; i < n ; ++ i ) {
181+ f [i ] = g [i - 1 ] + arr [i ] * ((i >> 1 ) + 1 );
182+ g [i ] = f [i - 1 ] + arr [i ] * ((i + 1 ) >> 1 );
183+ ans += f [i ];
181184 }
182185 return ans ;
183186}
@@ -189,15 +192,14 @@ function sumOddLengthSubarrays(arr: number[]): number {
189192impl Solution {
190193 pub fn sum_odd_length_subarrays (arr : Vec <i32 >) -> i32 {
191194 let n = arr . len ();
192- let mut ans = 0 ;
193- for i in 0 .. n {
194- let mut s = 0 ;
195- for j in i .. n {
196- s += arr [j ];
197- if (j - i + 1 ) % 2 == 1 {
198- ans += s ;
199- }
200- }
195+ let mut f = vec! [0 ; n ];
196+ let mut g = vec! [0 ; n ];
197+ let mut ans = arr [0 ];
198+ f [0 ] = arr [0 ];
199+ for i in 1 .. n {
200+ f [i ] = g [i - 1 ] + arr [i ] * ((i as i32 ) / 2 + 1 );
201+ g [i ] = f [i - 1 ] + arr [i ] * (((i + 1 ) as i32 ) / 2 );
202+ ans += f [i ];
201203 }
202204 ans
203205 }
@@ -208,15 +210,148 @@ impl Solution {
208210
209211``` c
210212int sumOddLengthSubarrays (int* arr, int arrSize) {
211- int ans = 0;
212- for (int i = 0; i < arrSize; ++i) {
213- int s = 0;
214- for (int j = i; j < arrSize; ++j) {
215- s += arr[ j] ;
216- if ((j - i + 1) % 2 == 1) {
217- ans += s;
218- }
213+ int n = arrSize;
214+ int f[ n] ;
215+ int g[ n] ;
216+ int ans = f[ 0] = arr[ 0] ;
217+ g[ 0] = 0;
218+ for (int i = 1; i < n; ++i) {
219+ f[ i] = g[ i - 1] + arr[ i] * (i / 2 + 1);
220+ g[ i] = f[ i - 1] + arr[ i] * ((i + 1) / 2);
221+ ans += f[ i] ;
222+ }
223+ return ans;
224+ }
225+ ```
226+
227+ <!-- tabs:end -->
228+
229+ <!-- solution:end -->
230+
231+ <!-- solution:start -->
232+
233+ ### 方法二:动态规划(空间优化)
234+
235+ 我们注意到,状态 $f[i]$ 和 $g[i]$ 的值只与 $f[i - 1]$ 和 $g[i - 1]$ 有关,因此我们可以使用两个变量 $f$ 和 $g$ 分别记录 $f[i - 1]$ 和 $g[i - 1]$ 的值,从而优化空间复杂度。
236+
237+ 时间复杂度 $O(n)$,空间复杂度 $O(1)$。
238+
239+ <!-- tabs:start -->
240+
241+ #### Python3
242+
243+ ```python
244+ class Solution:
245+ def sumOddLengthSubarrays(self, arr: List[int]) -> int:
246+ ans, f, g = arr[0], arr[0], 0
247+ for i in range(1, len(arr)):
248+ ff = g + arr[i] * (i // 2 + 1)
249+ gg = f + arr[i] * ((i + 1) // 2)
250+ f, g = ff, gg
251+ ans += f
252+ return ans
253+ ```
254+
255+ #### Java
256+
257+ ``` java
258+ class Solution {
259+ public int sumOddLengthSubarrays (int [] arr ) {
260+ int ans = arr[0 ], f = arr[0 ], g = 0 ;
261+ for (int i = 1 ; i < arr. length; ++ i) {
262+ int ff = g + arr[i] * (i / 2 + 1 );
263+ int gg = f + arr[i] * ((i + 1 ) / 2 );
264+ f = ff;
265+ g = gg;
266+ ans += f;
219267 }
268+ return ans;
269+ }
270+ }
271+ ```
272+
273+ #### C++
274+
275+ ``` cpp
276+ class Solution {
277+ public:
278+ int sumOddLengthSubarrays(vector<int >& arr) {
279+ int ans = arr[ 0] , f = arr[ 0] , g = 0;
280+ for (int i = 1; i < arr.size(); ++i) {
281+ int ff = g + arr[ i] * (i / 2 + 1);
282+ int gg = f + arr[ i] * ((i + 1) / 2);
283+ f = ff;
284+ g = gg;
285+ ans += f;
286+ }
287+ return ans;
288+ }
289+ };
290+ ```
291+
292+ #### Go
293+
294+ ```go
295+ func sumOddLengthSubarrays(arr []int) (ans int) {
296+ f, g := arr[0], 0
297+ ans = f
298+ for i := 1; i < len(arr); i++ {
299+ ff := g + arr[i]*(i/2+1)
300+ gg := f + arr[i]*((i+1)/2)
301+ f, g = ff, gg
302+ ans += f
303+ }
304+ return
305+ }
306+ ```
307+
308+ #### TypeScript
309+
310+ ``` ts
311+ function sumOddLengthSubarrays(arr : number []): number {
312+ const n = arr .length ;
313+ let [ans, f, g] = [arr [0 ], arr [0 ], 0 ];
314+ for (let i = 1 ; i < n ; ++ i ) {
315+ const ff = g + arr [i ] * (Math .floor (i / 2 ) + 1 );
316+ const gg = f + arr [i ] * Math .floor ((i + 1 ) / 2 );
317+ [f , g ] = [ff , gg ];
318+ ans += f ;
319+ }
320+ return ans ;
321+ }
322+ ```
323+
324+ #### Rust
325+
326+ ``` rust
327+ impl Solution {
328+ pub fn sum_odd_length_subarrays (arr : Vec <i32 >) -> i32 {
329+ let mut ans = arr [0 ];
330+ let mut f = arr [0 ];
331+ let mut g = 0 ;
332+ for i in 1 .. arr . len () {
333+ let ff = g + arr [i ] * ((i as i32 ) / 2 + 1 );
334+ let gg = f + arr [i ] * (((i + 1 ) as i32 ) / 2 );
335+ f = ff ;
336+ g = gg ;
337+ ans += f ;
338+ }
339+ ans
340+ }
341+ }
342+ ```
343+
344+ #### C
345+
346+ ``` c
347+ int sumOddLengthSubarrays (int* arr, int arrSize) {
348+ int ans = arr[ 0] , f = arr[ 0] , g = 0;
349+ for (int i = 1; i < arrSize; ++i) {
350+ int ff = g + arr[ i] * (i / 2 + 1);
351+ int gg = f + arr[ i] * ((i + 1) / 2);
352+ f = ff;
353+ g = gg;
354+ ans += f;
220355 }
221356 return ans;
222357}
0 commit comments