Leetcode--Java--525. 连续数组

题目描述

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

样例描述

示例 1:

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

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

思路

转换技巧 + 前缀和 + 哈希表

  1. 将所有的0换成-1,可以将问题转换为求最长的和为0的子数组
  2. 快速求一个区间的和,可以用前缀和数组。在求一段子数组的和可以表示为两个前缀和之差是否等于0,然后用哈希表的话,相当于看是否存在其中一个,只要其中一个存在,就存在整个。思路类似两数之和中对于每个x先找 target - x是否存在。这里是对于每个前缀和数组f[i] 是否存在f[j - 1],使得f[i] - f[j - 1] == 0,用哈希表也就是判断f[j - 1]是否存在
    在这里插入图片描述

代码

class Solution {
    public int findMaxLength(int[] nums) {
        int n = nums.length;
        int s[] = new int[n + 1];
        for (int i = 1; i <= n; i ++ ) {
            //0换成-1
            if (nums[i - 1] == 0) {
                nums[i - 1] = -1;
            }
            s[i] = s[i - 1] + nums[i - 1];
        }
        Map<Integer, Integer> map = new HashMap<>();
        int res = 0;
        //前缀和是1开始的,这里初始化边界问题
        map.put(0, 0);
        for (int i = 1; i <= n; i ++ ) {
            if (map.containsKey(s[i])) {
                res = Math.max(res, i - map.get(s[i]));
            } else {
                map.put(s[i], i);
            }
        }       
        return res;
    }
}

版权声明:本文为Sherlock_Obama原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。