给出一个二进制数组 data
,你需要通过交换位置,将数组中 任何位置 上的 1 组合到一起,并返回所有可能中所需 最少的交换次数。
示例 1:
输入: data = [1,0,1,0,1] 输出: 1 解释: 有三种可能的方法可以把所有的 1 组合在一起: [1,1,1,0,0],交换 1 次; [0,1,1,1,0],交换 2 次; [0,0,1,1,1],交换 1 次。 所以最少的交换次数为 1。
示例 2:
输入:data = [0,0,0,1,0] 输出:0 解释: 由于数组中只有一个 1,所以不需要交换。
示例 3:
输入:data = [1,0,1,0,1,0,0,1,1,0,1] 输出:3 解释: 交换 3 次,一种可行的只用 3 次交换的解决方案是 [0,0,0,0,0,1,1,1,1,1,1]。
示例 4:
输入: data = [1,0,1,0,1,0,1,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,1,0,1,1,0,0,0,1,1,1,1,0,0,1] 输出: 8
提示:
1 <= data.length <= 105
data[i]
==0
or1
.
思路:
我们首先要知道一共有多少个1, 假设数组里 1 的个数为 k。
接着我们可以利用滑动窗口的办法,找到长度为 k 的窗口里,最多有几个 1,假设最多有 c 个1。
那么现在对于这个窗口,需要移动的 1 的个数就是 k - c。
我们搜索所有窗口,找到这个 k - c 的最小值即可。
时间复杂度:O(N)
空间复杂度:O(1)
class Solution:
def minSwaps(self, data: List[int]) -> int:
# find the total number of 1 = k
# find a window of k that has most 1, where the cnt of 1 = c
# return k - c
# O(N), O(1)
k = data.count(1)
left = 0
c = 0
res = k
for right in range(len(data)):
if data[right] == 1:
c += 1
# move left
if right - left + 1 == k + 1:
if data[left] == 1:
c -= 1
left += 1
res = min(res, k - c)
return res