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

题目链接

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

题目描述

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

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

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

示例 2:

输入:nums = [1,1,0,0,1]
输出:0
解释:得益于数组的环形特性,所有的 1 已经聚集在一起。
因此,需要的最少交换次数为 0 。

提示:

  • 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
  • nums[i]0 或者 1

解法:固定滑动窗口

我们先记录 nums1的数量 len,即 固定滑动窗口的长度

每次我们只需要遍历每一个 固定滑动窗口 ,记录窗口内部 0 的数量,即 需要交换的次数。我们只需要记录最少的次数即可。

因为题目给定的是 环形数组,所以我们的 固定滑动窗口 也应该滑过 头和尾。所以我们再用一个数组 拼接到 nums后面,遍历这样一个长度为 2 * n的数组。

时间复杂度: O ( n ) O(n) O(n)

C++代码:


class Solution {
public:
    int minSwaps(vector<int>& nums) {
        int len = accumulate(nums.begin(),nums.end(),0);
        int n = nums.size() , cnt = 0;
        for(int i = 0;i < len;i++){
            if(!nums[i]) cnt++;
        }

        int ans = cnt;

        for(int i = 0,j = len;j < 2 * n;i++,j++){
            if(!nums[j % n]) cnt++;
            if(!nums[i % n]) cnt--;
            ans = min(ans,cnt);
        }

        return ans;
    }
};


你可能感兴趣的:(Leetcode,leetcode,算法,滑动窗口)