算法32,连续数组,前缀和+哈希表

题目

给定二进制数组 nums(只含 0 和 1),找出含有相同数量 0 和 1 ​ 的最长子数组,返回其长度。

核心思路:0 看作 -1,把问题转化为「和为 0 的最长子数组」

直接数 0 和 1 的个数很难,但做一个等价替换就豁然开朗:

  • 遇到 1 → 记 +1
  • 遇到 0 → 记 -1

记 prefix(i) 为前 i 项的和,那么区间 [j+1, i] 的和为:

复制代码
sum=prefix(i)−prefix(j)

区间和为 0 ⟺ 这段里 +1 和 -1 一样多 ⟺ 0 和 1 数量相等。

于是问题变成:找两个下标 i > j,使 prefix(i) == prefix(j),且 i - j 最大。这就是经典的「前缀和 + 哈希表」。

两个关键细节(笔记里也标了)

① 为什么要 map.put(0, -1)

当满足条件的子数组从头开始 时(即 prefix(i) == 0),它对应的「前一个位置」是数组开头之前,下标记为 -1。这样长度才是 i - (-1) = i + 1,而不是漏掉从 0 开始的情况。例如 nums = [0,1],i=1 时 sum=0,答案 = 1-(-1) = 2,正确。

② 遇到出现过的前缀和,只算长度、不能覆盖下标

求的是最长 ,同一个前缀和出现的位置越早,跨度越大。所以要保留首次出现的下标:

复制代码
if (map.containsKey(sum)) {
    ans = Math.max(ans, i - map.get(sum));
} else {
    map.put(sum, i);   // 只有没出现过才写,保证存的是最早下标
}

完整 Java 代码

复制代码
class Solution {
    public int findMaxLength(int[] nums) {
        Map<Integer, Integer> first = new HashMap<>();
        first.put(0, -1);              // 前缀和 0 出现在"数组开始前"
        int sum = 0, ans = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += (nums[i] == 0 ? -1 : 1);   // 0 视作 -1
            if (first.containsKey(sum)) {
                ans = Math.max(ans, i - first.get(sum));
            } else {
                first.put(sum, i);     // 只记录最早出现的下标
            }
        }
        return ans;
    }
}

复杂度:时间 O(n),一次遍历;空间 O(n),最坏情况 n 个前缀和互不相同。

手推一遍示例

nums = [0,1,1,0,1,1,1,0]

i numsi sum map 状态(关键值) 更新 ans
初始 --- 0 {0: -1} ---
0 0 -1 加 {-1: 0} ---
1 1 0 命中 0 → -1 1-(-1) = 2​
2 1 1 加 {1: 2} ---
3 0 0 命中 0 → -1 3-(-1) = 4​
4 1 1 命中 1 → 2 4-2 = 2
5 1 2 加 {2: 5} ---
6 1 3 加 {3: 6} ---
7 0 2 命中 2 → 5 7-5 = 2

答案 4 ,对应子数组 [1,1,0,1,1,0] 中的 [1,0,1,1,0]?------不对,取的是 i=3 处长度 4,即 [0,1,1,0](下标 0~3),恰好 2 个 0、2 个 1。

相关推荐
行者全栈架构师3 小时前
【鸿蒙心迹】冷启动从 2.8s 优化到 0.9s——耗时拆解与数据对比实战(HarmonyOS 7.x)
前端·算法·架构
LXY_BUAA3 小时前
《嵌入式操作系统》_framebuffer驱动_20261008
linux·运维·算法
Logic1013 小时前
C语言/数据结构字符串题解:统计“chhc“子串权值总和——一次遍历模式匹配
c语言·数据结构·算法·字符串·时间复杂度·空间复杂度·ascii
java_nnnn3 小时前
LeetCode刷题滑动窗口(最大连续1的个数三+将x减到0的最小操作数)Java
算法·leetcode·职场和发展
考研保研资料分享3 小时前
普通211核专业保研经验:清华预推免录取与北大、西交面试复盘
面试·职场和发展
背调与用工合规夏律师4 小时前
知情同意在跨境提供与境外接收方信息上的证据要求
职场和发展
bnmoel4 小时前
C++ 基础入门篇(六)类和对象-第三篇:运算符重载
开发语言·c++·算法·语法·运算符重载
wuyk5554 小时前
28 搜索引擎索引更新:从 LSM Tree 到布隆过滤器的高效实现
stm32·单片机·嵌入式硬件·算法
我命由我123454 小时前
LRU 缓存淘汰策略
数据结构·redis·学习·mysql·算法·缓存·学习方法
SunShaoLu4 小时前
流程图工具怎么选:5 款产品的技术对比与选型实践
人工智能·职场和发展·流程图·效率工具