525. 连续数组(前缀和+哈希)

这篇博客介绍了两种解决寻找具有相同数量0和1的最长连续子数组问题的方法。第一种是使用前缀和并进行暴力搜索,虽然超时但能解决问题;第二种方法更高效,利用前缀和结合哈希表,通过记录当前计数值及其对应索引,快速检查是否存在相同的计数值,从而找到最长子数组。这两种算法都针对给定的二进制数组,目标是找到最长的0和1数量相等的连续子数组。
摘要由CSDN通过智能技术生成

525. 连续数组

题目描述

难度中等356

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1

通过次数24,619

提交次数47,589

解1:前缀和+暴力(超时)

直接暴力,没啥好说的吧

class Solution {
    public int findMaxLength(int[] nums) {
        int n = nums.length;
        int[][] pre = new int[n + 1][2]; //pre[i][0]:nums[0..i-1]中0的个数
        pre[0][1] = 0;
        pre[0][0] = 0;
        for (int i = 1; i <= n; i++) {
            pre[i][0] = pre[i-1][0];
            pre[i][1] = pre[i-1][1];
            if(nums[i-1] == 0){
                pre[i][0]++;
            }else{
                pre[i][1]++;
            }
        }
        //暴力
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j <= n; j++) {
                if(pre[j][0] - pre[i][0] == pre[j][1] - pre[i][1]){
                    res = Math.max(res,j - i);
                }
            }
        }
        return res;
    }
}

请添加图片描述

解2:前缀和+哈希

思路:定义一个变量cur,然后遍历nums数组,碰到0就-1,碰到1就+1,这样如果数组两个地方的cur一样的话,就说明数组的这一块区域的0的个数==1的个数

使用哈希实现的思路是:每遍历完nums的一个地方之后,把cur当做key,当前索引当做value,存入哈希。然后要做的是检查当前哈希表是否存在相同的cur即可,如果存在,当前长度就是i - map[cur],再与res取最大值就行了。

代码:

class Solution {
    public int findMaxLength(int[] nums) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int res = 0;
        int cur = 0;
        map.put(0,-1);
        for (int i = 0; i < nums.length; i++) {
            if(nums[i] == 1){
                ++cur;
            }else{
                --cur;
            }
            Integer j = map.get(cur);
            if(j != null){
                res = Math.max(i - j,res);
            }else{
                //保证最大,所以如果存在cur这个key,就不要更新了,这样i-map[cur]才会更大
                map.put(cur,i);
            }
        }
        return res;
    }
}

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值