Q:给定一个数组 , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
数组问题,常规思路想先考虑【双端指针】,没有明确提示可以get到移动指针可以控制数据的膨胀和塌陷,so fail。
ok,双端指针失败,考虑【哈希遍历】方案,目前已知的这个方案的demo就是和为K的子数组问题,题目和已知方案似乎风马牛不相及。
so,转化一下,题目要求我们找到0和1个数相同的子数组,即【0,1】【1,0】差不多这样的结果。如果我们将0替换成-1,由于子数组内0,1数量相同,那么以上子数组有一个共同的特征,那就是和为0,则问题转化成功为求和为0的子数组问题。
综上所述,答案如下:
public static void main(String[] args) {
int [] array = new int []{0,1,0};
System.out.println(getArray(array));
}
private static int getArray(int[] array) {
int maxLength = 0,sum = 0;
//将sum作为key,代表曾经出现过的sum
//将index作为value,代表索引位置以便计算长度
Map<Integer,Integer> table = new HashMap<>(2);
//由于后续会将问题转变成和为K的数组问题,这里便如此设置
table.put(0,-1);
for (int i = 0; i < array.length; ++i) {
//这里进行替换 ,将0替换成-1,这样子数据内和为0,
// 问题就转成了和为0的子数组问题
int changeNum = array[i]== 0? -1:1;
sum += changeNum;
if (table.containsKey(sum)){
maxLength = Math.max(maxLength,i-table.get(sum));
}else {
table.put(sum,i);
}
}
return maxLength;
}