525. 连续数组
题目描述
难度中等356
给定一个二进制数组 nums
, 找到含有相同数量的 0
和 1
的最长连续子数组,并返回该子数组的长度。
示例 1:
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量0和1的最长连续子数组。
示例 2:
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
提示:
1 <= nums.length <= 105
nums[i]
不是0
就是1
通过次数24,619
提交次数47,589
解1:前缀和+暴力(超时)
直接暴力,没啥好说的吧
class Solution {
public int findMaxLength(int[] nums) {
int n = nums.length;
int[][] pre = new int[n + 1][2]; //pre[i][0]:nums[0..i-1]中0的个数
pre[0][1] = 0;
pre[0][0] = 0;
for (int i = 1; i <= n; i++) {
pre[i][0] = pre[i-1][0];
pre[i][1] = pre[i-1][1];
if(nums[i-1] == 0){
pre[i][0]++;
}else{
pre[i][1]++;
}
}
//暴力
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j <= n; j++) {
if(pre[j][0] - pre[i][0] == pre[j][1] - pre[i][1]){
res = Math.max(res,j - i);
}
}
}
return res;
}
}
解2:前缀和+哈希
思路:定义一个变量cur
,然后遍历nums
数组,碰到0就-1,碰到1就+1,这样如果数组两个地方的cur一样的话,就说明数组的这一块区域的0的个数==1的个数
使用哈希实现的思路是:每遍历完nums
的一个地方之后,把cur
当做key,当前索引当做value,存入哈希。然后要做的是检查当前哈希表是否存在相同的cur
即可,如果存在,当前长度就是i - map[cur]
,再与res取最大值就行了。
代码:
class Solution {
public int findMaxLength(int[] nums) {
HashMap<Integer,Integer> map = new HashMap<>();
int res = 0;
int cur = 0;
map.put(0,-1);
for (int i = 0; i < nums.length; i++) {
if(nums[i] == 1){
++cur;
}else{
--cur;
}
Integer j = map.get(cur);
if(j != null){
res = Math.max(i - j,res);
}else{
//保证最大,所以如果存在cur这个key,就不要更新了,这样i-map[cur]才会更大
map.put(cur,i);
}
}
return res;
}
}