525. Contiguous Array (Medium)

Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

Example 1:

Input: [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1.

Example 2:

Input: [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.

Note: The length of the given binary array will not exceed 50,000.

Solution 1: HashMap O(n); O(n)
[0,1,0,0,1,0,0,1,0]

这道题给了我们一个二进制的数组,让我们找邻近的子数组使其0和1的个数相等。对于求子数组的问题,我们需要时刻记着求累积和是一种很犀利的工具,但是这里怎么将子数组的和跟0和1的个数之间产生联系呢?我们需要用到一个trick,遇到1就加1,遇到0就减1,这样如果某个子数组和为0,就说明0和1的个数相等,这个想法真是太叼了。知道了这一点,我们用一个哈希表建立子数组之和跟结尾位置的坐标之间的映射。如果某个子数组之和在哈希表里存在了,说明当前子数组减去哈希表中存的那个子数字,得到的结果是中间一段子数组之和,必然为0,说明0和1的个数相等,我们更新结果res

    /**
     * HashMap O(n); O(n)
     * use counter to record the amount of 1 more than 0
     */
    public int findMaxLength(int[] nums) {
        if (nums == null) {
            return -1;
        }

        int count = 0; //use counter to record the amount of 1 more than 0
        Map<Integer, Integer> map = new HashMap<>(); //key:counter, value:index
        map.put(0, -1); //start from count 0, where is a virtual index of -1.
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            count += nums[i] == 0 ? -1 : 1; //遇到1就加1,遇到0就减1
            if (map.containsKey(count)) {
                res = Math.max(res, i - map.get(count));
            } else {
                map.put(count, i);
            }
        }
        return res;
    }
Solution 2: DP O(n); O(n)
    public int findMaxLengthB(int[] nums) {
        // 技巧1: 让 0 的时候的数变成-1, 1 的时候还是1. 这样就可以通过记录sum 是0 的位置来判断这个subarray;
        // 技巧2: 通过Array来存这个数是否之前出现 来加快速度。
        if (nums == null) {
            return -1;
        }

        int n = nums.length;
        int[] dp = new int[n * 2 + 1];
        dp[n] = -1;
        int count = n; // 通过这个来保证他前面都是正数的index
        int res = 0;
        for (int i = 0; i < n; i++) {
//            count += nums[i] + nums[i] - 1; // 通过这个来让0 -> -1
            count += nums[i] == 0 ? -1 : 1;
            if (dp[count] == 0) {
                dp[count] = i + 1;
            } else {
                res = dp[count] == -1 ? i + 1 : Math.max(res, i + 1 - dp[count]);
            }
        }
        return res;
    }

results matching ""

    No results matching ""