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

cicular array just append same array on it

but sliding win size (one count), should cal from the original array

T : O(n)

S: O(n)

class Solution {
    public int minSwaps(int[] nums) {
        int n = nums.length;

        int winSize = 0; // all 1's togeter will be the window size
        
        // for circular array, just need " append another same array " on the original array
        int[] data = new int[2*n]; 
        for (int i = 0; i < n; i++) {
            if (nums[i] == 1) {
                winSize++;
            }
            data[i] = nums[i];
            data[i+n] = nums[i];
        }
        
        int left = 0;
        int oneCount = 0; // count in this window, how many one
        int res = winSize;
        
        for (int right = 0; right < data.length; right++) {
            if (right - left + 1 > winSize) {
                oneCount -= data[left++];
            }
            oneCount += data[right];
            
            if (right - left + 1 == winSize) {
                // 0 needs to swap = winSize(total of ones) - one's count in window
                res = Math.min(res, winSize - oneCount); 
            }
        }
        return res;
        
    }
}

class Solution {
    public int minSwaps(int[] nums) {
        int n = nums.length;
        int oneWinSize = 0;

        int[] newNum = new int[n*2];
        for (int i = 0; i < n; i++) {
            if (nums[i] == 1) {
                oneWinSize++;
            }
            newNum[i] = nums[i];
            newNum[i+n] = nums[i]; 
        }

        if (oneWinSize == 0 || oneWinSize == 1) {
            return 0;
        }

        int left = 0;
        int result = Integer.MAX_VALUE;
        int zeroCount = 0;
        for (int right = 0; right < n*2; right++) {
            if (newNum[right] == 0) {
                zeroCount++;
            }
            if (right - left + 1 > oneWinSize) {
                if (newNum[left] == 0) {
                    zeroCount--;
                }
                left++;
            }
            if (right - left + 1 == oneWinSize) {
                result = Math.min(result, zeroCount);
            }
        }
        return result;
    }
}

/**
find how many one first




 0 1 2 3 4 5 6 7
[0,1,1,1,0,0,1,1,0][0,1,1,1,0,0,1,1,0]

for ex: this has 5 one

so try to find a win with 5 size, the min zero in this won -> it's the ans 

6 one
[1,1,1,0,0,1,0,1,1,0][1,1,1,0,0,1,0,1,1,0]
               x x x  x x x
for this win [1,1,0][1,1,1] , only one zero in this window -> so ans is 1




Inital wrong thought:
if we only try to find a max win has 6 one, in the end max win - one's count
-> in  [1,1,1,0,0,1,0,1,1,0][1,1,1,0,0,1,0,1,1,0]
will be wrong
because a win has 6 one, is 1,0,1,1,0][1,1,1 or 1,1,1,0,0,1,0,1,1 (become 8 - 6 = 2 or 9 - 6 = 3)
both are not the correct ans
 */

Last updated