{x}
blog image

Minimum Swaps to Group All 1's Together II

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.

Solution Explanation: Minimum Swaps to Group All 1's Together II

This problem asks for the minimum swaps needed to group all 1s together in a circular binary array. The circular nature means we can wrap around from the end to the beginning.

Solution 1: Sliding Window (Optimal)

This approach leverages the sliding window technique for efficiency.

  1. Count 1s: First, count the total number of 1s in the array (k). This represents the length of the contiguous block of 1s we aim to create.

  2. Initial Window: Create a window of size k at the beginning of the array. Count the number of 1s within this initial window (cnt). This cnt represents the number of 1s already grouped within the window. The number of swaps needed for this initial window is k - cnt.

  3. Sliding Window: Slide the window one element at a time to the right. For each slide:

    • Subtract the value of the element leaving the window from cnt.
    • Add the value of the newly entered element to cnt.
    • Update the maximum number of 1s encountered in any window (mx).
  4. Minimum Swaps: The minimum number of swaps required is k - mx, where mx is the maximum number of 1s found in any window. This is because mx represents the best grouping of 1s achievable, and k - mx represents the number of 0s within that optimal window that need to be swapped out.

Time Complexity: O(n), where n is the length of the array. The sliding window iterates through the array once.

Space Complexity: O(1), as we only use a few constant extra variables.

Solution 2: Prefix Sum (Less Efficient)

This approach uses prefix sums to calculate the number of 1s (or 0s) in different subarrays. It's less efficient than the sliding window approach.

  1. Helper Function getMin: This function takes a target value (0 or 1) as input. It calculates the prefix sum array for that target value. The prefix sum at index i stores the count of the target value from index 0 up to i.

  2. Iterate Through Subarrays: It then iterates through all possible subarrays of length equal to the total count of the target value. For each subarray, it calculates the number of the target value present, and finds the minimum number of swaps needed to group all instances of that target value together.

  3. Minimum of 0s and 1s: Finally, it returns the minimum of the minimum swaps needed to group 0s and the minimum swaps needed to group 1s.

Time Complexity: O(n^2), in the worst case due to the nested loops in getMin. This approach is less efficient than the sliding window approach for larger arrays.

Space Complexity: O(n) for the prefix sum array.

Code Examples (Python for Solution 1):

from collections import Counter
 
class Solution:
    def minSwaps(self, nums: List[int]) -> int:
        k = Counter(nums)[1]  # Count of 1s
        n = len(nums)
        max_ones = current_ones = sum(nums[:k])  #Initial window
        for i in range(k, n + k):
            current_ones += nums[i % n] - nums[(i - k) % n] #slide
            max_ones = max(max_ones, current_ones)
        return k - max_ones
 

The provided code in other languages follows the same logic as the Python Solution 1 (sliding window) adjusting syntax for the specific language. Solution 2 (prefix sum) is less efficient and is generally not recommended for this problem.