Space-efficient algorithm for finding the largest balanced subarray?

后端 未结 10 1214
谎友^
谎友^ 2020-12-22 22:54

given an array of 0s and 1s, find maximum subarray such that number of zeros and 1s are equal. This needs to be done in O(n) time and O(1) space.

I have an algo whic

10条回答
  •  余生分开走
    2020-12-22 23:45

    I have this algorithm running in O(n) time and O(1) space.

    It makes use of simple "shrink-then-expand" trick. Comments in codes.

    public static void longestSubArrayWithSameZerosAndOnes() {
        // You are given an array of 1's and 0's only.
        // Find the longest subarray which contains equal number of 1's and 0's
        int[] A = new int[] {1, 0, 1, 1, 1, 0, 0,0,1};
        int num0 = 0, num1 = 0;
    
        // First, calculate how many 0s and 1s in the array
        for(int i = 0; i < A.length; i++) {
            if(A[i] == 0) {
                num0++;
            }
            else {
                num1++;
            }
        }
        if(num0 == 0 || num1 == 0) {
            System.out.println("The length of the sub-array is 0");
            return;
        }
    
        // Second, check the array to find a continuous "block" that has
        // the same number of 0s and 1s, starting from the HEAD and the
        // TAIL of the array, and moving the 2 "pointer" (HEAD and TAIL)
        // towards the CENTER of the array
        int start = 0, end = A.length - 1;
        while(num0 != num1 && start < end) {
            if(num1 > num0) {
                if(A[start] == 1) {
                    num1--; start++;
                }
                else if(A[end] == 1) {
                    num1--; end--;
                }
                else {
                    num0--; start++;
                    num0--; end--;
                }
            }
            else if(num1 < num0) {
                if(A[start] == 0) {
                    num0--; start++;
                }
                else if(A[end] == 0) {
                    num0--; end--;
                }
                else {
                    num1--; start++;
                    num1--; end--;
                }
            }
        }
        if(num0 == 0 || num1 == 0) {
            start = end;
            end++;
        }
    
        // Third, expand the continuous "block" just found at step #2 by
        // moving "HEAD" to head of the array and "TAIL" to the end of
        // the array, while still keeping the "block" balanced(containing
        // the same number of 0s and 1s
        while(0 < start && end < A.length - 1) {
            if(A[start - 1] == 0 && A[end + 1] == 0 || A[start - 1] == 1 && A[end + 1] == 1) {
                break;
            }
            start--;
            end++;
        }
        System.out.println("The length of the sub-array is " + (end - start + 1) + ", starting from #" + start + " to #" + end);
    

    }

提交回复
热议问题