题目
交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。
环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。
给你一个 二进制环形 数组 nums ,返回在 任意位置 将数组中的所有 1 聚集在一起需要的最少交换次数。
示例1
输入:nums = [0,1,0,1,1,0,0]
输出:1
解释:这里列出一些能够将所有 1 聚集在一起的方案:
[0,0,1,1,1,0,0] 交换 1 次。
[0,1,1,1,0,0,0] 交换 1 次。
[1,1,0,0,0,0,1] 交换 2 次(利用数组的环形特性)。
无法在交换 0 次的情况下将数组中的所有 1 聚集在一起。
因此,需要的最少交换次数为 1 。
前言
竞赛的时候没有想出来,惭愧
题解
滑动窗口
- 统计数组中共有多少1
- 根据1的数量设置窗口大小
- 统计窗口中0的数量
- 因为是循环数组,所以数组nums合并自身得到list
- 在数组list中统计窗口中0存在的数量,0数量最小的个数即为交换需要的次数
根据上述思路编辑代码如下
代码
var minSwaps = function (nums) {
const len = nums.length
let one = 0
for (let i = 0; i < len; i++) {
if (nums[i] === 1) one++
}
let zreo = 0
for (let i = 0; i < one; i++) {
if (nums[i] === 0) zreo++
}
let min = Infinity
const list = nums.concat(nums)
min = Math.min(min, zreo)
for (let i = one; i < list.length; i++) {
if (list[i] === 0) {
zreo = zreo + 1
}
if (list[i - one] === 0) {
zreo = zreo - 1
}
min = Math.min(min, zreo)
}
return min
}