一、题目
给定一个二进制数组 nums
, 找到含有相同数量的 0
和 1
的最长连续子数组,并返回该子数组的长度。
二、思路
1)前缀和+哈希表
题意容易混淆,需注意理解。
相同数量的0和1最长连续子数组,这句话意思是子数组连续,但其中的0和1不一定连续(也就是内部是怎样的排列都可以),只要数量相等。
假设连续子数组在[i, j]区间,使用暴力法需要穷举该区间,时间复杂度肯定超。
使用前缀和可以O(1)时间获取[i, j]区间的和,记录为sum[j]-sum[i],将nums中的0看作-1,那么当相同数量的0和1时,sum[j]-sum[i]=0,即sum[j]=sum[i].使用哈希表,根据sum[j]查找sum[i]就可以。
三、代码
1)前缀和+哈希表
class Solution {
public int findMaxLength(int[] nums) {
int[] sum = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
sum[i+1] = sum[i] + (nums[i] == 0 ? -1 : 1);
}
Map<Integer, Integer> map = new HashMap();
int ans = 0;
for (int i = 2; i < sum.length; i++) {
// 如果之前存过同样的元素,就不存(即取最远的那个值,使连续子数组长度最长)
if (!map.containsKey(sum[i-2])) {
map.put(sum[i-2], i-2);
}
if (map.containsKey(sum[i])) {
ans = Math.max(ans, i - map.get(sum[i]));
}
}
return ans;
}
}
时间复杂度为O(n),空间复杂度为O(n)。