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

Difficulty
Medium
Tags
滑动窗口
URL
https://leetcode.cn/problems/minimum-swaps-to-group-all-1s-together-ii/
Star
交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。
环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻
给你一个 二进制环形 数组 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 。
示例 2:
输入:nums = [0,1,1,1,0,0,1,1,0] 输出:2 解释:这里列出一些能够将所有 1 聚集在一起的方案: [1,1,1,0,0,0,0,1,1] 交换 2 次(利用数组的环形特性)。 [1,1,1,1,1,0,0,0,0] 交换 2 次。 无法在交换 0 次或 1 次的情况下将数组中的所有 1 聚集在一起。 因此,需要的最少交换次数为 2 。
示例 3:
输入:nums = [1,1,0,0,1] 输出:0 解释:得益于数组的环形特性,所有的 1 已经聚集在一起。 因此,需要的最少交换次数为 0 。
提示:
  • 1 <= nums.length <= 105
  • nums[i]0 或者 1

滑动窗口

思路
思路:将所有的1放在一起,那么可以考虑一个大小为S(S为数组中1的总个数)的窗口,然后遍历所有的窗口,找到其中1个数最多的的窗口,那么最少的交换次数就是该窗口中0的个数
题解
class Solution: def minSwaps(self, nums: List[int]) -> int: length = sum(nums) l, r = 0, 0 res = 0 wds = 0 while r < len(nums) * 2: wds += 1 if nums[r%len(nums)] == 1 else 0 r += 1 if r-l > length: wds -= 1 if nums[l%len(nums)] == 1 else 0 l += 1 if r-l == length: res = max(res, wds) return length - res