[LeetCode] 2134. Minimum Swaps to Group All 1s Together II

CNoodle發表於2024-08-04

A swap is defined as taking two distinct positions in an array and swapping the values in them.

A circular array is defined as an array where we consider the first element and the last element to be adjacent.

Given a binary circular array nums, return the minimum number of swaps required to group all 1's present in the array together at any location.

Example 1:
Input: nums = [0,1,0,1,1,0,0]
Output: 1
Explanation: Here are a few of the ways to group all the 1's together:
[0,0,1,1,1,0,0] using 1 swap.
[0,1,1,1,0,0,0] using 1 swap.
[1,1,0,0,0,0,1] using 2 swaps (using the circular property of the array).
There is no way to group all 1's together with 0 swaps.
Thus, the minimum number of swaps required is 1.

Example 2:
Input: nums = [0,1,1,1,0,0,1,1,0]
Output: 2
Explanation: Here are a few of the ways to group all the 1's together:
[1,1,1,0,0,0,0,1,1] using 2 swaps (using the circular property of the array).
[1,1,1,1,1,0,0,0,0] using 2 swaps.
There is no way to group all 1's together with 0 or 1 swaps.
Thus, the minimum number of swaps required is 2.

Example 3:
Input: nums = [1,1,0,0,1]
Output: 0
Explanation: All the 1's are already grouped together due to the circular property of the array.
Thus, the minimum number of swaps required is 0.

Constraints:
1 <= nums.length <= 105
nums[i] is either 0 or 1.

最少交換次數來組合所有的 1 II。

交換 定義為選中一個陣列中的兩個 互不相同 的位置並交換二者的值。 環形 陣列是一個陣列,可以認為 第一個 元素和 最後一個 元素 相鄰 。 給你一個 二進位制環形 陣列 nums ,返回在 任意位置 將陣列中的所有 1 聚集在一起需要的最少交換次數。

思路

這道題跟版本一 1151 題很像,唯一不同的地方是題目多了一個條件,給的 input 是環形陣列。環形陣列中找連續的 1 的個數其實是比較難的,因為最優解有可能是斷開的(一部分 1 在陣列起點,一部分 1 在陣列終點),但是我們可以換一種思路。因為 input 陣列中只有 0 和 1 兩種數字,那麼我們可以試著比較把所有的 1 聚集在一起的開銷少還是把所有的 0 聚集在一起的開銷少。

複雜度

時間O(n)
空間O(1)

程式碼

Java實現

class Solution {
    public int minSwaps(int[] nums) {
        int n = nums.length;
        int ones = 0;
        int zeros = 0;
        for (int num : nums) {
            if (num == 0) {
                zeros++;
            }
        }
        ones = n - zeros;

        int a = helper(nums, 0, zeros);
        int b = helper(nums, 1, ones);
        return Math.min(a, b);
    }

    private int helper(int[] nums, int target, int p) {
        int start = 0;
        int end = 0;
        int count = 0;
        int res = Integer.MAX_VALUE;
        while (end < nums.length) {
            if (nums[end] == target) {
                count++;
            }
            end++;
            if (end - start == p) {
                res = Math.min(res, p - count);
                if (nums[start] == target) {
                    count--;
                }
                start++;
            }
        }
        return res;
    }
}

相關題目

1151. Minimum Swaps to Group All 1s Together
2134. Minimum Swaps to Group All 1s Together II

相關文章