1. 问题背景与转化思路
今天想和大家分享一道LeetCode上关于连续数组的经典题目(525题)。这道题要求我们找到一个包含相同数量0和1的最长连续子数组。乍一看似乎需要统计0和1的个数,但通过一个巧妙的转化,我们可以将其变成一个更易处理的问题。
关键在于将数组中的0全部替换为-1。这样,原问题就等价于寻找和为0的最长连续子数组。因为当子数组中0和1数量相等时,-1和1的总和恰好为0。这个转化让问题瞬间清晰了许多,也让我们能够运用前缀和这一强大工具来解决问题。
提示:这种将二元分类问题转化为数值计算问题的技巧,在很多算法题中都非常有用,比如处理正负元素平衡、字符匹配等问题时都可以考虑类似思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前缀和与哈希表解法详解
2.1 前缀和基础概念
前缀和(Prefix Sum)是一种预处理技术,通过计算数组中从起始位置到当前位置的所有元素之和,将许多区间求和问题转化为简单的差值计算。对于数组nums,其前缀和数组prefix定义为:
prefix[i] = nums[0] + nums[1] + ... + nums[i-1]
在这个问题中,我们不需要显式地存储整个前缀和数组,只需要维护一个运行总和(running sum)即可,这可以节省空间复杂度。
2.2 哈希表的特殊用法
与常见的前缀和问题不同,这里我们使用哈希表来记录每个前缀和第一次出现的位置,而不是出现次数。这是因为我们需要找到的是最长的子数组,而不是所有可能的子数组。
哈希表的键是前缀和的值,值是该前缀和第一次出现的下标位置。这种设计让我们能够在O(1)时间内检查某个前缀和是否曾经出现过,并获取其最早出现位置。
2.3 初始化的巧妙之处
在开始遍历数组前,我们需要初始化哈希表,存入hash[0] = -1。这个操作看似奇怪,实则精妙:
- 它表示在数组开始前(下标-1处),前缀和为0
- 这样当整个数组从开始到某位置i的前缀和为0时,我们可以正确计算出子数组长度为i - (-1) = i+1
- 没有这个初始化,我们就无法正确处理从数组开头开始的符合条件的子数组
3. 完整代码实现与逐行解析
cpp复制class Solution {
public:
int findMaxLength(vector<int>
