【Leetcode算法题】525. 连续数组

By Long Luo

525. 连续数组题目如下:

  1. 连续数组
    给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。

示例 1:
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。

示例 2:
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。

提示:
1 <= nums.length <= 10^5
nums[i] 不是 0 就是 1

方法一:暴力遍历

思路与算法:

首先想到的方法是暴力遍历,第一层循环,索引i0n,第二层循环则是计算到i+1n01的数量,如果相等,则更新最大长度\textit{maxLength}

代码如下所示:

public int findMaxLength(int[] nums) {
    if (nums == null || nums.length <= 1) {
        return 0;
    }

    int ans = 0;
    int n = nums.length;
    int zeroNum = 0;
    int oneNum = 0;
    for (int i = 0; i < n; i++) {
        zeroNum = 0;
        oneNum = 0;
        if (nums[i] == 0) {
            zeroNum++;
        } else {
            oneNum++;
        }

        for (int j = i + 1; j < n; j++) {
            if (nums[j] == 0) {
                zeroNum++;
            } else {
                oneNum++;
            }

            if (zeroNum == oneNum) {
                ans = Math.max(ans, 2 * zeroNum);
            }
        }
    }

    return ans;
}

复杂度分析:

  • 时间复杂度:O(N^2),其中N是数组\textit{nums}的长度。
  • 空间复杂度:O(1),多了2个记录01的数量变量。

方法二:哈希表 + 前缀和

思路与算法:

方法一的暴力还是太慢了,涉及到连续的数组元素,第一想到的是可以使用前缀和。如果i<j,prefix[j]-prefix[j]等于j - i / 2的,则认为i到j之间0和1的个数是一样的。我们可以先计算出数组的前缀和数组,然后再遍历一遍,求出最长的子数组。

实际上这种思路还有一个更巧妙的方法:那就是将0视作-1,则原问题转换成“求最长的连续子数组,其元素和为0”。

实现方面,不需要创建数组\textit{newNums}\textit{prefixSums},只需要维护一个变量\textit{counter}存储\textit{newNums}的前缀和即可。具体做法是,遍历数组\textit{nums},当遇到元素1时将\textit{counter}的值加1,当遇到元素0时将\textit{counter}的值减1,遍历过程中使用哈希表存储每个前缀和第一次出现的下标。

如果\textit{counter}的值在哈希表中已经存在,则取出\textit{counter}在哈希表中对应的下标\textit{prevIndex}\textit{nums}从下标\textit{prevIndex}+1到下标i的子数组中有相同数量的01,该子数组的长度为i-\textit{prevIndex},使用该子数组的长度更新最长连续子数组的长度;

如果\textit{counter}的值在哈希表中不存在,则将当前余数和当前下标i的键值对存入哈希表中。

由于哈希表存储的是\textit{counter}的每个取值第一次出现的下标,因此当遇到重复的前缀和时,根据当前下标和哈希表中存储的下标计算得到的子数组长度是以当前下标结尾的子数组中满足有相同数量的01的最长子数组的长度。遍历结束时,即可得到\textit{nums}中的有相同数量的01的最长子数组的长度。

代码如下所示:

public int findMaxLength(int[] nums) {
    if (nums == null || nums.length <= 1) {
        return 0;
    }

    int ans = 0;
    int n = nums.length;
    Map<Integer, Integer> map = new HashMap<>();
    int sum = 0;
    map.put(0, -1);
    for (int i = 0; i < n; i++) {
        if (nums[i] == 1) {
            sum++;
        } else {
            sum--;
        }
        if (map.containsKey(sum)) {
            int prevIndex = map.get(sum);
            ans = Math.max(ans, i - prevIndex);
        } else {
            map.put(sum, i);
        }
    }

    return ans;
}

复杂度分析:

  • 时间复杂度:O(N),其中N是数组\textit{nums}的长度。
  • 空间复杂度:O(N),其中N是数组\textit{nums}的长度。
    空间复杂度主要取决于哈希表,哈希表中存储的不同的\textit{counter}的值不超过N个。

原文链接:【Leetcode算法题】525. 连续数组

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容