@@ -88,32 +88,295 @@ tags:
88
88
89
89
<!-- solution:start -->
90
90
91
- ### 方法一
91
+ ### 方法一:贪心 + 前缀和 + 二分查找
92
+
93
+ 我们考虑枚举 Alice 的站立位置 $i$,对于每个 $i$,我们按照如下的策略进行操作:
94
+
95
+ - 首先,如果位置 $i$ 的数字为 $1$,我们可以直接拾取一个 $1$,不需要行动次数。
96
+ - 然后,我们对 $i$ 的左右两侧位置的数字 $1$ 进行拾取,执行的是行动 $2$,即把位置 $i-1$ 的 $1$ 移到位置 $i$,然后拾取;把位置 $i+1$ 的 $1$ 移到位置 $i$,然后拾取。每拾取一个 $1$,需要 $1$ 次行动。
97
+ - 接下来,我们最大限度地将 $i-1$ 或 $i+1$ 上的 $0$,利用行动 $1$,将其置为 $1$,然后利用行动 $2$,将其移动到位置 $i$,拾取。直到拾取的 $1$ 的数量达到 $k$ 或者行动 $1$ 的次数达到 $\text{maxChanges}$。我们假设行动 $1$ 的次数为 $c$,那么总共需要 $2c$ 次行动。
98
+ - 利用完行动 $1$,如果拾取的 $1$ 的数量还没有达到 $k$,我们需要继续考虑在 $[ 1,..i-2] $ 和 $[ i+2,..n] $ 的区间内,进行行动 $2$,将 $1$ 移动到位置 $i$,拾取。我们可以使用二分查找来确定这个区间的大小,使得拾取的 $1$ 的数量达到 $k$。具体地,我们二分枚举一个区间的大小 $d$,然后在区间 $[ i-d,..i-2] $ 和 $[ i+2,..i+d] $ 内,进行行动 $2$,将 $1$ 移动到位置 $i$,拾取。如果拾取的 $1$ 的数量达到 $k$,我们就更新答案。
99
+
100
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\text{nums}$ 的长度。
92
101
93
102
<!-- tabs:start -->
94
103
95
104
#### Python3
96
105
97
106
``` python
98
-
107
+ class Solution :
108
+ def minimumMoves (self , nums : List[int ], k : int , maxChanges : int ) -> int :
109
+ n = len (nums)
110
+ cnt = [0 ] * (n + 1 )
111
+ s = [0 ] * (n + 1 )
112
+ for i, x in enumerate (nums, 1 ):
113
+ cnt[i] = cnt[i - 1 ] + x
114
+ s[i] = s[i - 1 ] + i * x
115
+ ans = inf
116
+ max = lambda x , y : x if x > y else y
117
+ min = lambda x , y : x if x < y else y
118
+ for i, x in enumerate (nums, 1 ):
119
+ t = 0
120
+ need = k - x
121
+ for j in (i - 1 , i + 1 ):
122
+ if need > 0 and 1 <= j <= n and nums[j - 1 ] == 1 :
123
+ need -= 1
124
+ t += 1
125
+ c = min (need, maxChanges)
126
+ need -= c
127
+ t += c * 2
128
+ if need <= 0 :
129
+ ans = min (ans, t)
130
+ continue
131
+ l, r = 2 , max (i - 1 , n - i)
132
+ while l <= r:
133
+ mid = (l + r) >> 1
134
+ l1, r1 = max (1 , i - mid), max (0 , i - 2 )
135
+ l2, r2 = min (n + 1 , i + 2 ), min (n, i + mid)
136
+ c1 = cnt[r1] - cnt[l1 - 1 ]
137
+ c2 = cnt[r2] - cnt[l2 - 1 ]
138
+ if c1 + c2 >= need:
139
+ t1 = c1 * i - (s[r1] - s[l1 - 1 ])
140
+ t2 = s[r2] - s[l2 - 1 ] - c2 * i
141
+ ans = min (ans, t + t1 + t2)
142
+ r = mid - 1
143
+ else :
144
+ l = mid + 1
145
+ return ans
99
146
```
100
147
101
148
#### Java
102
149
103
150
``` java
104
-
151
+ class Solution {
152
+ public long minimumMoves (int [] nums , int k , int maxChanges ) {
153
+ int n = nums. length;
154
+ int [] cnt = new int [n + 1 ];
155
+ long [] s = new long [n + 1 ];
156
+ for (int i = 1 ; i <= n; ++ i) {
157
+ cnt[i] = cnt[i - 1 ] + nums[i - 1 ];
158
+ s[i] = s[i - 1 ] + i * nums[i - 1 ];
159
+ }
160
+ long ans = Long . MAX_VALUE ;
161
+ for (int i = 1 ; i <= n; ++ i) {
162
+ long t = 0 ;
163
+ int need = k - nums[i - 1 ];
164
+ for (int j = i - 1 ; j <= i + 1 ; j += 2 ) {
165
+ if (need > 0 && 1 <= j && j <= n && nums[j - 1 ] == 1 ) {
166
+ -- need;
167
+ ++ t;
168
+ }
169
+ }
170
+ int c = Math . min(need, maxChanges);
171
+ need -= c;
172
+ t += c * 2 ;
173
+ if (need <= 0 ) {
174
+ ans = Math . min(ans, t);
175
+ continue ;
176
+ }
177
+ int l = 2 , r = Math . max(i - 1 , n - i);
178
+ while (l <= r) {
179
+ int mid = (l + r) >> 1 ;
180
+ int l1 = Math . max(1 , i - mid), r1 = Math . max(0 , i - 2 );
181
+ int l2 = Math . min(n + 1 , i + 2 ), r2 = Math . min(n, i + mid);
182
+ int c1 = cnt[r1] - cnt[l1 - 1 ];
183
+ int c2 = cnt[r2] - cnt[l2 - 1 ];
184
+ if (c1 + c2 >= need) {
185
+ long t1 = 1L * c1 * i - (s[r1] - s[l1 - 1 ]);
186
+ long t2 = s[r2] - s[l2 - 1 ] - 1L * c2 * i;
187
+ ans = Math . min(ans, t + t1 + t2);
188
+ r = mid - 1 ;
189
+ } else {
190
+ l = mid + 1 ;
191
+ }
192
+ }
193
+ }
194
+ return ans;
195
+ }
196
+ }
105
197
```
106
198
107
199
#### C++
108
200
109
201
``` cpp
110
-
202
+ class Solution {
203
+ public:
204
+ long long minimumMoves(vector<int >& nums, int k, int maxChanges) {
205
+ int n = nums.size();
206
+ vector<int > cnt(n + 1, 0);
207
+ vector<long long > s(n + 1, 0);
208
+
209
+ for (int i = 1; i <= n; ++i) {
210
+ cnt[i] = cnt[i - 1] + nums[i - 1];
211
+ s[i] = s[i - 1] + 1LL * i * nums[i - 1];
212
+ }
213
+
214
+ long long ans = LLONG_MAX;
215
+
216
+ for (int i = 1 ; i <= n; ++i) {
217
+ long long t = 0;
218
+ int need = k - nums[i - 1];
219
+
220
+ for (int j = i - 1; j <= i + 1; j += 2) {
221
+ if (need > 0 && 1 <= j && j <= n && nums[j - 1] == 1) {
222
+ --need;
223
+ ++t;
224
+ }
225
+ }
226
+
227
+ int c = min(need, maxChanges);
228
+ need -= c;
229
+ t += c * 2;
230
+
231
+ if (need <= 0) {
232
+ ans = min(ans, t);
233
+ continue;
234
+ }
235
+
236
+ int l = 2, r = max(i - 1, n - i);
237
+
238
+ while (l <= r) {
239
+ int mid = (l + r) / 2;
240
+ int l1 = max(1, i - mid), r1 = max(0, i - 2);
241
+ int l2 = min(n + 1, i + 2), r2 = min(n, i + mid);
242
+
243
+ int c1 = cnt[r1] - cnt[l1 - 1];
244
+ int c2 = cnt[r2] - cnt[l2 - 1];
245
+
246
+ if (c1 + c2 >= need) {
247
+ long long t1 = 1LL * c1 * i - (s[r1] - s[l1 - 1]);
248
+ long long t2 = s[r2] - s[l2 - 1] - 1LL * c2 * i;
249
+ ans = min(ans, t + t1 + t2);
250
+ r = mid - 1;
251
+ } else {
252
+ l = mid + 1;
253
+ }
254
+ }
255
+ }
256
+
257
+ return ans;
258
+ }
259
+ };
111
260
```
112
261
113
262
#### Go
114
263
115
264
``` go
265
+ func minimumMoves (nums []int , k int , maxChanges int ) int64 {
266
+ n := len (nums)
267
+ cnt := make ([]int , n+1 )
268
+ s := make ([]int , n+1 )
269
+
270
+ for i := 1 ; i <= n; i++ {
271
+ cnt[i] = cnt[i-1 ] + nums[i-1 ]
272
+ s[i] = s[i-1 ] + i*nums[i-1 ]
273
+ }
274
+
275
+ ans := math.MaxInt64
276
+
277
+ for i := 1 ; i <= n; i++ {
278
+ t := 0
279
+ need := k - nums[i-1 ]
280
+
281
+ for _ , j := range []int {i - 1 , i + 1 } {
282
+ if need > 0 && 1 <= j && j <= n && nums[j-1 ] == 1 {
283
+ need--
284
+ t++
285
+ }
286
+ }
287
+
288
+ c := min (need, maxChanges)
289
+ need -= c
290
+ t += c * 2
291
+
292
+ if need <= 0 {
293
+ ans = min (ans, t)
294
+ continue
295
+ }
296
+
297
+ l , r := 2 , max (i-1 , n-i)
298
+
299
+ for l <= r {
300
+ mid := (l + r) >> 1
301
+ l1 , r1 := max (1 , i-mid), max (0 , i-2 )
302
+ l2 , r2 := min (n+1 , i+2 ), min (n, i+mid)
303
+
304
+ c1 := cnt[r1] - cnt[l1-1 ]
305
+ c2 := cnt[r2] - cnt[l2-1 ]
306
+
307
+ if c1+c2 >= need {
308
+ t1 := c1*i - (s[r1] - s[l1-1 ])
309
+ t2 := s[r2] - s[l2-1 ] - c2*i
310
+ ans = min (ans, t+t1+t2)
311
+ r = mid - 1
312
+ } else {
313
+ l = mid + 1
314
+ }
315
+ }
316
+ }
317
+
318
+ return int64 (ans)
319
+ }
320
+ ```
116
321
322
+ #### TypeScript
323
+
324
+ ``` ts
325
+ function minimumMoves(nums : number [], k : number , maxChanges : number ): number {
326
+ const n = nums .length ;
327
+ const cnt = Array (n + 1 ).fill (0 );
328
+ const s = Array (n + 1 ).fill (0 );
329
+
330
+ for (let i = 1 ; i <= n ; i ++ ) {
331
+ cnt [i ] = cnt [i - 1 ] + nums [i - 1 ];
332
+ s [i ] = s [i - 1 ] + i * nums [i - 1 ];
333
+ }
334
+
335
+ let ans = Infinity ;
336
+ for (let i = 1 ; i <= n ; i ++ ) {
337
+ let t = 0 ;
338
+ let need = k - nums [i - 1 ];
339
+
340
+ for (let j of [i - 1 , i + 1 ]) {
341
+ if (need > 0 && 1 <= j && j <= n && nums [j - 1 ] === 1 ) {
342
+ need -- ;
343
+ t ++ ;
344
+ }
345
+ }
346
+
347
+ const c = Math .min (need , maxChanges );
348
+ need -= c ;
349
+ t += c * 2 ;
350
+
351
+ if (need <= 0 ) {
352
+ ans = Math .min (ans , t );
353
+ continue ;
354
+ }
355
+
356
+ let l = 2 ,
357
+ r = Math .max (i - 1 , n - i );
358
+
359
+ while (l <= r ) {
360
+ const mid = (l + r ) >> 1 ;
361
+ const [l1, r1] = [Math .max (1 , i - mid ), Math .max (0 , i - 2 )];
362
+ const [l2, r2] = [Math .min (n + 1 , i + 2 ), Math .min (n , i + mid )];
363
+
364
+ const c1 = cnt [r1 ] - cnt [l1 - 1 ];
365
+ const c2 = cnt [r2 ] - cnt [l2 - 1 ];
366
+
367
+ if (c1 + c2 >= need ) {
368
+ const t1 = c1 * i - (s [r1 ] - s [l1 - 1 ]);
369
+ const t2 = s [r2 ] - s [l2 - 1 ] - c2 * i ;
370
+ ans = Math .min (ans , t + t1 + t2 );
371
+ r = mid - 1 ;
372
+ } else {
373
+ l = mid + 1 ;
374
+ }
375
+ }
376
+ }
377
+
378
+ return ans ;
379
+ }
117
380
```
118
381
119
382
<!-- tabs:end -->
0 commit comments