zoukankan      html  css  js  c++  java
  • leetcode 525. Contiguous Array

    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的最长连续子数组的长度。

    方法一:暴力法(超时)


    C++代码

    我们考虑所有的连续子数组,判断0和1个数是否相同,如果相同,则与当前已找到的符合条件的连续子数组的长度进行比较。

     1  int findMaxLength(vector<int>& nums) {
     2         int sum = 0;
     3         int maxsize = 0;
     4         for (int i = 0; i < nums.size(); ++i) {
     5             sum = 0;
     6             for (int j = i; j < nums.size(); ++j) {
     7                 //计算[i,j]的和,[i, j]的和=[i,j-1]的和+j,所以可以利用前面得到的结果
     8                 (nums[j] == 1) ? (sum += 1) : (sum -= 1);
     9                 if (sum == 0 && (maxsize < j - i + 1)) {
    10                     maxsize = j - i + 1;
    11                 }
    12             }
    13         }
    14         return maxsize;
    15     }

    在这里,我们讨论索引[i,j]中1和0的个数是否相等时,避免直接统计1和0的个数,而是利用累加和,是1则加1,0则减1,累加和为0则代表1和0个数相同。

    时间复杂度:$O(n^2)$

    空间复杂度:$O(1)$


    方法二:哈希表

    假设S[i]表示数组索引为0到i的子数组各元素之和(遇到1则加1,遇到0则减1),如果S[i]=0,那么[0,i]组成的子数组是符合条件的;

    假如S[i] !=0 且 S[i] = m,然而存在最小的$j in [0,i)$使得S[j] = m,那么[j+1, i]是符合条件的连续子数组。因为S[i]=S[j],我们要根据累加和m,得到索引j,所以需要建立累加和映射到索引的哈希表。

    累加和的取值范围为[-n, n](n为数组的长度,-n时表示数组全为-1, n时表示数组全为1),所以开辟一个2n+1的数组。

     1 int findMaxLength(vector<int>& nums) {
     2         int len = nums.size();
     3         vector<int> index(2 * len + 1, -2); //初始化为-2表示这些累加和尚未出现
     4         index[len] = -1; //一开始累加和为0,索引为-1
     5         int maxlen = 0, sum = 0;
     6         for (int i = 0; i < nums.size(); ++i) {
     7             sum += (nums[i] == 0) ? -1 : 1;
     8             if (index[sum + len] >= -1) { //如果当前累加和已经出现过,则比较大小并更新maxlen,这里就不用更新累加和对应的索引
     9                 maxlen = max(maxlen, i - index[sum + len]);
    10             } else { //否则记录累加和对应的索引
    11                 index[sum + len] = i;
    12             }
    13         }
    14         return maxlen;
    15     }

    需要注意的是,累加和为m可能对应多个索引,因为要找最长的连续子数组,所以我们只能保存最小的索引。

    时间复杂度:$O(n)$

    空间复杂度:$O(n)$

    或者利用STL map数据结构:

     1 int findMaxLength(vector<int>& nums) {
     2         int len = nums.size();
     3         unordered_map<int, int> hM;
     4         int maxlen = 0, sum = 0;
     5         for (int i = 0; i < nums.size(); ++i) {
     6             sum += (nums[i] == 0) ? -1 : 1;
     7             if (sum == 0)
     8                 maxlen = i + 1;
     9             if (hM.find(sum + len) != hM.end()) { 
    10                 maxlen = max(maxlen, i - hM[sum + len]);
    11             } else {
    12                 hM[sum + len] = i;
    13             }
    14         }
    15         return maxlen;
    16     }

  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/13040796.html
Copyright © 2011-2022 走看看