拾起 K 个 1 需要的最少行动次数
难度:
标签:
题目描述
You are given a binary array nums
of length n
, a positive integer k
and a non-negative integer maxChanges
.
Alice plays a game, where the goal is for Alice to pick up k
ones from nums
using the minimum number of moves. When the game starts, Alice picks up any index aliceIndex
in the range [0, n - 1]
and stands there. If nums[aliceIndex] == 1
, Alice picks up the one and nums[aliceIndex]
becomes 0
(this does not count as a move). After this, Alice can make any number of moves (including zero) where in each move Alice must perform exactly one of the following actions:
- Select any index
j != aliceIndex
such thatnums[j] == 0
and setnums[j] = 1
. This action can be performed at mostmaxChanges
times. - Select any two adjacent indices
x
andy
(|x - y| == 1
) such thatnums[x] == 1
,nums[y] == 0
, then swap their values (setnums[y] = 1
andnums[x] = 0
). Ify == aliceIndex
, Alice picks up the one after this move andnums[y]
becomes0
.
Return the minimum number of moves required by Alice to pick exactly k
ones.
Example 1:
Input: nums = [1,1,0,0,0,1,1,0,0,1], k = 3, maxChanges = 1
Output: 3
Explanation: Alice can pick up 3
ones in 3
moves, if Alice performs the following actions in each move when standing at aliceIndex == 1
:
- At the start of the game Alice picks up the one and
nums[1]
becomes0
.nums
becomes[1,1,1,0,0,1,1,0,0,1]
. - Select
j == 2
and perform an action of the first type.nums
becomes[1,0,1,0,0,1,1,0,0,1]
- Select
x == 2
andy == 1
, and perform an action of the second type.nums
becomes[1,1,0,0,0,1,1,0,0,1]
. Asy == aliceIndex
, Alice picks up the one andnums
becomes[1,0,0,0,0,1,1,0,0,1]
. - Select
x == 0
andy == 1
, and perform an action of the second type.nums
becomes[0,1,0,0,0,1,1,0,0,1]
. Asy == aliceIndex
, Alice picks up the one andnums
becomes[0,0,0,0,0,1,1,0,0,1]
.
Note that it may be possible for Alice to pick up 3
ones using some other sequence of 3
moves.
Example 2:
Input: nums = [0,0,0,0], k = 2, maxChanges = 3
Output: 4
Explanation: Alice can pick up 2
ones in 4
moves, if Alice performs the following actions in each move when standing at aliceIndex == 0
:
- Select
j == 1
and perform an action of the first type.nums
becomes[0,1,0,0]
. - Select
x == 1
andy == 0
, and perform an action of the second type.nums
becomes[1,0,0,0]
. Asy == aliceIndex
, Alice picks up the one andnums
becomes[0,0,0,0]
. - Select
j == 1
again and perform an action of the first type.nums
becomes[0,1,0,0]
. - Select
x == 1
andy == 0
again, and perform an action of the second type.nums
becomes[1,0,0,0]
. Asy == aliceIndex
, Alice picks up the one andnums
becomes[0,0,0,0]
.
Constraints:
2 <= n <= 105
0 <= nums[i] <= 1
1 <= k <= 105
0 <= maxChanges <= 105
maxChanges + sum(nums) >= k
代码结果
运行时间: 112 ms, 内存: 27.2 MB
/*
题目思路:
1. 首先找到所有为1的索引,记录在一个列表中。
2. 如果这些1的数量已经大于等于k,则直接在这些1中选择相隔最远的k个1即可。
3. 如果1的数量少于k,则需要利用maxChanges将0变为1,再进行选择。
4. 使用滑动窗口的方法计算最小行动次数。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
public int minMoves(int[] nums, int k, int maxChanges) {
List<Integer> ones = IntStream.range(0, nums.length)
.filter(i -> nums[i] == 1)
.boxed()
.collect(Collectors.toList());
if (ones.size() >= k) {
return ones.get(k - 1) - ones.get(0);
}
int additional = k - ones.size();
int minMoves = Integer.MAX_VALUE;
for (int i = 0; i + k - 1 < nums.length; i++) {
int moves = 0;
int changes = 0;
for (int j = i; j < i + k; j++) {
if (nums[j] == 0) {
changes++;
}
}
if (changes <= maxChanges) {
minMoves = Math.min(minMoves, moves);
}
}
return minMoves;
}
}
解释
方法:
时间复杂度:
空间复杂度: