@@ -159,32 +159,209 @@ source: 第 469 场周赛 Q2
159
159
160
160
<!-- solution:start -->
161
161
162
- ### 方法一
162
+ ### 方法一: 前缀和 + 双数组记录单调性
163
+
164
+ 我们用一个前缀和数组 $s$ 来记录数组的前缀和,其中 $s[ i] $ 表示数组 $[ 0,..i] $ 的和。然后我们用两个布尔数组 $f$ 和 $g$ 来分别记录前缀和后缀的单调性,其中 $f[ i] $ 表示数组 $[ 0,..i] $ 是否严格递增,而 $g[ i] $ 表示数组 $[ i,..n-1] $ 是否严格递减。
165
+
166
+ 最后,我们遍历数组位置 $i,ドル其中 0ドル \leq i < n-1,ドル如果 $f[ i] $ 和 $g[ i+1] $ 都为真,那么我们就可以计算出 $left$ 和 $right$ 的和,分别为 $s[ i] $ 和 $s[ n-1] -s[ i] ,ドル并更新答案。
167
+
168
+ 时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
163
169
164
170
<!-- tabs:start -->
165
171
166
172
#### Python3
167
173
168
174
``` python
169
-
175
+ class Solution :
176
+ def splitArray (self , nums : List[int ]) -> int :
177
+ s = list (accumulate(nums))
178
+ n = len (nums)
179
+ f = [True ] * n
180
+ for i in range (1 , n):
181
+ f[i] = f[i - 1 ]
182
+ if nums[i] <= nums[i - 1 ]:
183
+ f[i] = False
184
+ g = [True ] * n
185
+ for i in range (n - 2 , - 1 , - 1 ):
186
+ g[i] = g[i + 1 ]
187
+ if nums[i] <= nums[i + 1 ]:
188
+ g[i] = False
189
+ ans = inf
190
+ for i in range (n - 1 ):
191
+ if f[i] and g[i + 1 ]:
192
+ s1 = s[i]
193
+ s2 = s[n - 1 ] - s[i]
194
+ ans = min (ans, abs (s1 - s2))
195
+ return ans if ans < inf else - 1
170
196
```
171
197
172
198
#### Java
173
199
174
200
``` java
175
-
201
+ class Solution {
202
+ public long splitArray (int [] nums ) {
203
+ int n = nums. length;
204
+ long [] s = new long [n];
205
+ s[0 ] = nums[0 ];
206
+ boolean [] f = new boolean [n];
207
+ Arrays . fill(f, true );
208
+ boolean [] g = new boolean [n];
209
+ Arrays . fill(g, true );
210
+ for (int i = 1 ; i < n; ++ i) {
211
+ s[i] = s[i - 1 ] + nums[i];
212
+ f[i] = f[i - 1 ];
213
+ if (nums[i] <= nums[i - 1 ]) {
214
+ f[i] = false ;
215
+ }
216
+ }
217
+ for (int i = n - 2 ; i >= 0 ; -- i) {
218
+ g[i] = g[i + 1 ];
219
+ if (nums[i] <= nums[i + 1 ]) {
220
+ g[i] = false ;
221
+ }
222
+ }
223
+ final long inf = Long . MAX_VALUE ;
224
+ long ans = inf;
225
+ for (int i = 0 ; i < n - 1 ; ++ i) {
226
+ if (f[i] && g[i + 1 ]) {
227
+ long s1 = s[i];
228
+ long s2 = s[n - 1 ] - s[i];
229
+ ans = Math . min(ans, Math . abs(s1 - s2));
230
+ }
231
+ }
232
+ return ans < inf ? ans : - 1 ;
233
+ }
234
+ }
176
235
```
177
236
178
237
#### C++
179
238
180
239
``` cpp
181
-
240
+ class Solution {
241
+ public:
242
+ long long splitArray(vector<int >& nums) {
243
+ int n = nums.size();
244
+ vector<long long > s(n);
245
+ s[ 0] = nums[ 0] ;
246
+ vector<bool > f(n, true), g(n, true);
247
+
248
+ for (int i = 1; i < n; ++i) {
249
+ s[i] = s[i - 1] + nums[i];
250
+ f[i] = f[i - 1];
251
+ if (nums[i] <= nums[i - 1]) {
252
+ f[i] = false;
253
+ }
254
+ }
255
+ for (int i = n - 2 ; i >= 0 ; --i) {
256
+ g[i] = g[i + 1];
257
+ if (nums[i] <= nums[i + 1]) {
258
+ g[i] = false;
259
+ }
260
+ }
261
+
262
+ const long long inf = LLONG_MAX;
263
+ long long ans = inf;
264
+ for (int i = 0; i < n - 1; ++i) {
265
+ if (f[i] && g[i + 1]) {
266
+ long long s1 = s[i];
267
+ long long s2 = s[n - 1] - s[i];
268
+ ans = min(ans, llabs(s1 - s2));
269
+ }
270
+ }
271
+ return ans < inf ? ans : -1;
272
+ }
273
+ };
182
274
```
183
275
184
276
#### Go
185
277
186
278
``` go
279
+ func splitArray (nums []int ) int64 {
280
+ n := len (nums)
281
+ s := make ([]int64 , n)
282
+ f := make ([]bool , n)
283
+ g := make ([]bool , n)
284
+ for i := range f {
285
+ f[i] = true
286
+ g[i] = true
287
+ }
288
+
289
+ s[0 ] = int64 (nums[0 ])
290
+ for i := 1 ; i < n; i++ {
291
+ s[i] = s[i-1 ] + int64 (nums[i])
292
+ f[i] = f[i-1 ]
293
+ if nums[i] <= nums[i-1 ] {
294
+ f[i] = false
295
+ }
296
+ }
297
+ for i := n - 2 ; i >= 0 ; i-- {
298
+ g[i] = g[i+1 ]
299
+ if nums[i] <= nums[i+1 ] {
300
+ g[i] = false
301
+ }
302
+ }
303
+
304
+ const inf = int64 (^uint64 (0 ) >> 1 )
305
+ ans := inf
306
+ for i := 0 ; i < n-1 ; i++ {
307
+ if f[i] && g[i+1 ] {
308
+ s1 := s[i]
309
+ s2 := s[n-1 ] - s[i]
310
+ ans = min (ans, abs (s1-s2))
311
+ }
312
+ }
313
+ if ans < inf {
314
+ return ans
315
+ }
316
+ return -1
317
+ }
318
+
319
+ func abs (x int64 ) int64 {
320
+ if x < 0 {
321
+ return -x
322
+ }
323
+ return x
324
+ }
325
+ ```
187
326
327
+ #### TypeScript
328
+
329
+ ``` ts
330
+ function splitArray(nums : number []): number {
331
+ const n = nums .length ;
332
+ const s: number [] = Array (n );
333
+ const f: boolean [] = Array (n ).fill (true );
334
+ const g: boolean [] = Array (n ).fill (true );
335
+
336
+ s [0 ] = nums [0 ];
337
+ for (let i = 1 ; i < n ; ++ i ) {
338
+ s [i ] = s [i - 1 ] + nums [i ];
339
+ f [i ] = f [i - 1 ];
340
+ if (nums [i ] <= nums [i - 1 ]) {
341
+ f [i ] = false ;
342
+ }
343
+ }
344
+
345
+ for (let i = n - 2 ; i >= 0 ; -- i ) {
346
+ g [i ] = g [i + 1 ];
347
+ if (nums [i ] <= nums [i + 1 ]) {
348
+ g [i ] = false ;
349
+ }
350
+ }
351
+
352
+ const INF = Number .MAX_SAFE_INTEGER;
353
+ let ans = INF ;
354
+
355
+ for (let i = 0 ; i < n - 1 ; ++ i ) {
356
+ if (f [i ] && g [i + 1 ]) {
357
+ const s1 = s [i ];
358
+ const s2 = s [n - 1 ] - s [i ];
359
+ ans = Math .min (ans , Math .abs (s1 - s2 ));
360
+ }
361
+ }
362
+
363
+ return ans < INF ? ans : - 1 ;
364
+ }
188
365
```
189
366
190
367
<!-- tabs:end -->
0 commit comments