Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d50c095

Browse files
feat: add solutions to lc problem: No.3086 (doocs#3199)
No.3086.Minimum Moves to Pick K Ones
1 parent f2a4791 commit d50c095

File tree

7 files changed

+787
-8
lines changed

7 files changed

+787
-8
lines changed

‎solution/3000-3099/3086.Minimum Moves to Pick K Ones/README.md‎

Lines changed: 267 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,32 +88,295 @@ tags:
8888

8989
<!-- solution:start -->
9090

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,ドル那么总共需要 2ドルc$ 次行动。
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}$ 的长度。
92101

93102
<!-- tabs:start -->
94103

95104
#### Python3
96105

97106
```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
99146
```
100147

101148
#### Java
102149

103150
```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+
}
105197
```
106198

107199
#### C++
108200

109201
```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+
};
111260
```
112261

113262
#### Go
114263

115264
```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+
```
116321

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+
}
117380
```
118381

119382
<!-- tabs:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /