【LeetCode】这么简单的题,豆编又不会!

简介: 【LeetCode】这么简单的题,豆编又不会!

【LeetCode】这么简单的题,豆编又不会!

题目信息

525 - 连续数组

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
【 Tips 】
1 <= nums.length <= 10^5
nums[i] 不是 0 就是 1
=================================================
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量0和1的最长连续子数组。
=================================================
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
=================================================
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/contiguous-array/

菜编思路

这个不难,这几天的题都是一样的类型,前缀数组和加上哈希表的套路。

  1. 这里可以做一次转化,把数组中的 0 换成 -1 去做处理,这样一个含有相同数量的 0 和 1 的连续数组的和就是 0
  2. 当连续数组和为 0 时,加上这个连续数组的前缀数组,和不加上这个连续数组的前缀数组,他们两个的和都是一样的。
  3. 我们记录前缀数组之和第一次出现的位置,然后再次遇到相同和时,求两次位置的差值

参考代码

public int findMaxLength(int[] nums) {
  int len = nums.length;
  if (len < 2)
    return 0;
  Map<Integer, Integer> map = new HashMap<>();
  // 位置 0 之前的前缀数组之和记做0,位置记做-1
  map.put(0, -1);
  // 前缀数组之和
  int sum = 0;
  // 记录最大的数组
  int max = 0;
  for (int i = 0; i < len; i++) {
    if (nums[i] == 1) {
      sum += 1;
    } else {
      sum += -1;
    }
    if (map.containsKey(sum)) {
      if (i - map.get(sum) > max)
        max = i - map.get(sum);
    } else {
      map.put(sum, i);
    }
  }
  return max;
}

这段代码理解起来很容易,思路很清晰,能看明白就好,今天的文章到此为止……


优雅升级

本来以为这样就结束了,豆编兴高采烈的提交完代码以后,发现运行速度处于下游水平,运行速度比最快的慢了近 5 倍……


这不行啊,然后就分析了一波上上上游水平的代码什么样子的。

public int findMaxLength(int[] nums) {
  // 数组长度
  int len = nums.length;
  // 定义一个长度时nums两倍的数组,存放前缀和对应的位置
  int[] sums = new int[2 * len + 1];
  // 最大的数组长度
  int max = 0;
  // 前缀数组的和
  int sum = 0;
  for (int i = 0; i < len; ++i) {
    // 计算前缀数组的和,0 替换成 -1处理
    sum += nums[i] == 0 ? -1 : 1;
    // 当sum为0时,表示这是个从头开始的数组,一定是当前最长的
    if (sum == 0)
      max = i + 1;
    // 位置数组的默认位置为0,当不是0时,这个和在之前出现过
    else if (sums[sum + len] != 0)
      max = Math.max(max, i - sums[sum + len] + 1);
    else
      // +1操作是为了避免位置为 0 时,sums数组存放 0,跟默认值冲突
      sums[sum + len] = i + 1;
  }
  return max;
}

这是一个空间换时间的算法,大体上还是一样的思想,只是细节上有些不一样。

这个解法有意思啊,这个两倍数组实现了哈希表的作用,存放位置信息,前缀和最小为 nums 长度的负值,这里不会出现数组越界。

前缀和为 0 时,出现的数组一定是当前最长的,避免了其他判断。

这里有一点容易出错的地方,就是i0 时,直接存放数组中,会跟默认值冲突,导致 else if 的判断失效,拿不到 0 位置上的前缀数组和。

最重要的是看懂了以后,要去自己实现一遍

目录
相关文章
|
2天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1292 1
|
9天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
698 4
|
2天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
557 3
|
3天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
|
2天前
|
存储 弹性计算 安全
阿里云服务器4核8G收费标准和活动价格参考:u2a实例898.20元起,计算型c9a3459.05元起
现在租用阿里云服务器4核8G价格是多少?具体价格及配置详情如下:云服务器ECS通用算力型u2a实例,配备4核8G配置、1M带宽及40G ESSD云盘(作为系统盘),其活动价格为898.20元/1年起;此外,ECS计算型c9a实例4核8G配置搭配20G ESSD云盘,活动价格为3459.05元/1年起。在阿里云的当前活动中,4核8G云服务器提供了多种实例规格供用户选择,不同实例规格及带宽的组合将带来不同的优惠价格。本文为大家解析阿里云服务器4核8G配置的实例规格收费标准与最新活动价格情况,以供参考。
238 150
|
9天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
356 164