题目
知识点
思路
- 我们可以将这题转换为”前缀和“去做,遇到
1
则和+1,遇到0
则和-1。 - 求出的
sum
在以前遇到过(用哈希表记录,只需要记录第一次),说明中间的部分就是具有含有相同数量的0
和1
的连续子数组,然后更新长度即可,以如下例子为例:(index) -1, 0, 1, 2, 3, 4, 5, 6, 7
(num) /, 0, 1, 1, 0, 1, 1, 1, 0
(sum) 0, -1, 0, 1, 0, 2, 3, 4, 3
- 在上述的例子中,索引为-1(前面没有元素时
sum
也等于1)和1、-1和3、5和7和是相同的,最长的子数组长度为4。 - 为什么哈希表只记录第一次出现某个sum值得索引?
因为要保证最长的子数组,如果每次都更新,比如上述例子中得-1、1、3
,那么必然不是最长的(最长得肯定是要出现最早的)。 - 怎么想到前缀和?
我们可以把这个前缀和理解为爬山的高度,1是向上1步,-1是向下1步,从n
到n
意味着到达了相同海拔的位置,那么必然是经过了相同爬上和爬下的次数,也就是含有相同数量的 0 和 1 的连续子数组了。
代码
class Solution {
public:
unordered_map<int, int> mp;
int findMaxLength(vector<int> &nums) {
mp[0] = -1;
int sum = 0, max_len = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] == 1) sum++;
else sum--;
if (mp.count(sum)) {
max_len = max(max_len, i - mp[sum]);
} else {
mp[sum] = i;
}
}
return max_len;
}
};