Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 525. Contiguous Array #525

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 525. Contiguous Array #525

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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.

 

这道题给了我们一个二进制的数组,让找邻近的子数组使其0和1的个数相等。对于求子数组的问题,需要时刻记着求累积和是一种很犀利的工具,但是这里怎么将子数组的和跟0和1的个数之间产生联系呢?这里需要用到一个 trick,遇到1就加1,遇到0,就减1,这样如果某个子数组和为0,就说明0和1的个数相等,这个想法真是太叼了,不过博主木有想出来。知道了这一点,就用一个 HashMap 建立子数组之和跟结尾位置的坐标之间的映射。如果某个子数组之和在 HashMap 里存在了,说明当前子数组减去 HashMap 中存的那个子数字,得到的结果是中间一段子数组之和,必然为0,说明0和1的个数相等,更新结果 res。注意这里需要在 HashMap 初始化一个 0 -> -1 的映射,这是为了当 sum 第一次出现0的时候,即这个子数组是从原数组的起始位置开始,需要计算这个子数组的长度,而不是建立当前子数组之和 sum 和其结束位置之间的映射。比如就拿例子1来说,nums = [0, 1],当遍历0的时候,sum = -1,此时建立 -1 -> 0 的映射,当遍历到1的时候,此时 sum = 0 了,若 HashMap 中没有初始化一个 0 -> -1 的映射,此时会建立 0 -> 1 的映射,而不是去更新这个满足题意的子数组的长度,所以要这么初始化,参见代码如下:

 

解法一:

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        int res = 0, n = nums.size(), sum = 0;
        unordered_map<int, int> m{{0, -1}};
        for (int i = 0; i < n; ++i) {
            sum += (nums[i] == 1) ? 1 : -1;
            if (m.count(sum)) {
                res = max(res, i - m[sum]);
            } else {
                m[sum] = i;
            }
        }
        return res;
    }
};

 

下面这种方法跟上面的解法基本上完全一样,只不过在求累积和的时候没有用条件判断,而是用了一个很叼的等式直接包括了两种情况,参见代码如下:

 

解法二:

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        int res = 0, n = nums.size(), sum = 0;
        unordered_map<int, int> m{{0, -1}};
        for (int i = 0; i < n; ++i) {
            sum += (nums[i] << 1) -1;
            if (m.count(sum)) {
                res = max(res, i - m[sum]);
            } else {
                m[sum] = i;
            }
        }
        return res;
    }
};

 

Github 同步地址:

#525

 

类似题目:

Maximum Size Subarray Sum Equals k 

 

参考资料:

https://leetcode.com/problems/contiguous-array/

https://leetcode.com/problems/contiguous-array/discuss/99646/Easy-Java-O(n)-Solution-PreSum-%2B-HashMap

https://leetcode.com/problems/contiguous-array/discuss/99652/One-passuse-a-HashMap-to-record-0-1-count-difference

 

LeetCode All in One 题目讲解汇总(持续更新中...) 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant