1.未排序正数数组中累加和为给定值的最长子数组长度
2.未排序数组中累加和为给定值的最长子数组长度(包含正数和负数)
3.给定数组中包含正数、负数、0,求正数与负数相等的最长子数组的长度
4.给定数组只包含1、0,求所有子数组中0、1个数相等的最长子数组的长度
问题1
使用left,right分别表示当前数组的开始和结束位置,累加和为Sum;
case: sum>target 则left++;
case:sum==target 则试图更新maxLen,并且left++;
case:sum
int getMaxLenPositiveArray(int[] array,int target){
if (array==null || array.length==0 || target<=0){
return 0;
}
int sum = array[0],left=0,right=0,len=array.length,max = 0;
while(right<len){
if(sum == target){
max = Math.max(max,right-left+1);
sum -= array[left++];
} else if(sum<target){
right++;
if(right<len){
sum+=array[right];
}
}else {
sum -= array[left++];
}
}
return max;
}
问题2
如果subSum[0,j]-subSum[0,i]==target,则数组中{i,j}之间的元素和则为target.
基于这样的思想,我们选用map结构来记录Key最早出现的位置,例如: {2,1,-3,4,1,-2},target==2,则生成的map为:{(2,0),(3,1),(0,2),(4,3),(5,4)},当遍历到位置4的时候,subSum{0,4}==5,
5-target=5-2=3,那么3出现的最早位置为1,所以我们知道从位置2(由1+1而来)到位置4的和为target==2,找到满足条件之后则更新MaxLen即可。
int getMaxLenArray(int[]array,int target){
if(array==null || array.length==0){
return 0;
}
Map<Integer,Integer> map = new HashMap<>();
int sum = 0;
map.put(0,-1);
int max = 0;
for(int i=0;i<array.length;i++){
sum += array[i];
if(!map.containsKey(sum)){
map.put(sum,i);
}
if(map.containsKey(sum-target)){
max = Math.max(max,i-map.get(sum-target));
}
}
return max;
}
问题3
根据问题2,令target==0,把数组中的负数变为-1,正数变为1即可。
int getMaxLenPositiveEqualNegnative(int[]array){
int[] array2 = new int[array.length];
for(int i=0;i<array.length;i++){
if(array[i]>0){
array2[i] = 1;
}else if(array[i]<0){
array2[i] = -1;
}else{
array2[i] = array[i];
}
}
return getMaxLenArray(array2,0);
}
问题4
根据问题2,令target==0,把数组中0变为-1,即可。
int getMaxLen1Equal0(int[]array){
int[]array2 = new int[array.length];
for(int i=0;i<array.length;i++){
if(array[i]==0){
array2[i] = -1;
}else{
array2[i] = array[i];
}
}
return getMaxLenArray(array2,0);
}