最少交换次数来组合所有的 1 II

351 阅读1分钟

5977. 最少交换次数来组合所有的 1 II

题目

交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。

环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。

给你一个 二进制环形 数组 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
}