Leetcode_C++之525. Contiguous Array(连续子数组)

题目名称

Contiguous Array

题目描述

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

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

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

Constraints:
1 <= nums.length <= 10e5
nums[i] is either 0 or 1.

初试思路

见注释和视频b站

初试代码

// 我的代码
class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        // 遍历从下标i到下标j的子串中符合条件的最长的子串,返回其长度
        // 即count0[i to j] == count1[i to j] 
        // => count0[0 to j] - count0[0 to i] == count1[0 to j] - count1[0 to i]
        // => count0[0 to j] - count1[0 to j] == count0[0 to i] - count1[0 to i]
        // => diffcount[j] == diffcount[i]
        // 遍历找到符合条件的最大的 i to j的长度

        int MaxLen = 0; //最大子串长度
        int MaxJ = 0;   //最大的j的值
        // diffcount数组存放nums中从下标0到每个下标的“0的个数与1的个数差”,其长度为nums.size()+1,原因见初始化
        vector<int> diffcount(nums.size()+1); // -1 0 1 2 ... nums.size()-1
        diffcount[dindex(-1)] = 0; //下标0之前的下标“-1”对应的元素置零0
        // 初始化diffcount数组, 如果nums[i]==0,则将diffcount[dindex(i)]的值置为前一个元素+1
        //                      如果nums[i]==1,则将diffcount[dindex(i)]的值置为前一个元素-1
        for(int i=0; i<nums.size(); i++){
            if(nums[i]==0)
                diffcount[dindex(i)] = diffcount[dindex(i-1)]+1;
            else
                diffcount[dindex(i)]= diffcount[dindex(i-1)]-1;
        }
        // maxj数组存放所有可能的“0的个数与1的个数差”的最大的下标j是几,其长度为nums.size()*2+1
        // 这也是一个空间换时间的做法,将循环操作换为数组查表
        vector<int> maxj(nums.size()*2+1); // -nums.size ... 0 ... nums.size()
        for(int i=-nums.size(); i<nums.size(); i++){
            maxj[mindex(i, nums.size())] = -1; //初始化为-1。这是一个稀疏数组,很多元素都不会被用到
        }
        //设置maxj个元素的值
        for(int j=0; j<nums.size(); j++){
            maxj[mindex(diffcount[dindex(j)], nums.size())] = j; // 当出现相同的diffcount时,会被更大的j覆盖
        }
        //遍历所有可能的diffcount,找到最大的j - i + 1 = MaxLen的值
        for(int i=0; i<nums.size(); i++){
            int target = diffcount[dindex(i-1)];
            MaxJ = maxj[mindex(target, nums.size())];
            if(MaxJ-i > MaxLen) //if(MaxJ-i+1 > MaxLen) //会使得Maxlen = 1而这明显是错的
                MaxLen = MaxJ-i+1;    
        }
        return MaxLen;   
    }

    int dindex(int i){
        return i+1;
    }
    int mindex(int i, int size){
        return i+size;
    }

};

推荐思路

1、一个数组即可,存放当前0的个数和1的个数的差
2、因为数组是稀疏的,好多用不到,所以可以用哈希表

推荐代码

// 别人的代码1
class Solution {
public:
    int findMaxLength(vector<int>& nums) {
		vector<int> arr(2*nums.size() + 1, INT_MIN);
		arr[nums.size()] = -1;
        int maxLen = 0, sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += (nums[i] == 0 ? -1 : 1);
			if (arr[sum + nums.size()] >= -1)  maxLen = max(maxLen, i - arr[sum + nums.size()]);
			else  arr[sum + nums.size()] = i; 
        }
        return maxLen;
    }
};
//别人的代码2
class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        int sum=0, maxLen=0;
        unordered_map<int, int> seen{{0, -1}};
        
        for(int i=0; i<nums.size(); i++){
            sum += nums[i]==1 ? 1 : -1;
            if(seen.count(sum)) maxLen = max(maxLen, i-seen[sum]);
            else seen[sum] = i;
        }
        return maxLen;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值