给定一个数组arr,和一个整数num,求在arr中,累加和等于num的最长 子数组的长度
例子:
arr = {7,3,2,1,1,7,7,7}
num = 7 其中有很多的子数组累加和等于7,但是最长的子数组是{3,2,1,1},所 以返回其长度4
public static int zzzi_sumisit(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
hashMap.put(0, -1);
int len = 0;
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
if (hashMap.containsKey(sum - k)) {
len = Math.max(i - hashMap.get(sum - k), len);
}
if (!hashMap.containsKey(sum)) {
hashMap.put(sum, i);
}
}
return len;
}
衍生(最长奇偶长度):
public class zzzi_sumisit2 {
public static int zzzi_sumisit2(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
hashMap.put(0, -1);
int len = 0;
int sum = 0;
int[] bra = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
bra[i] = arr[i] % 2 == 1 ? 1 : -1;
sum += bra[i];
if (hashMap.containsKey(sum - k)) {
len = Math.max(i - hashMap.get(sum - k), len);
}
if (!hashMap.containsKey(sum)) {
hashMap.put(sum, i);
}
}
return len;
}
衍生:(最长1&2数量长度):
public class zzzi_sumisit3 {
public static int zzzi_sumisit3(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
hashMap.put(0, -1);
int len = 0;
int sum = 0;
int[] help = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 2) {
help[i] = -1;
} else if (arr[i] == 1) {
help[i] = 1;
} else {
help[i] = 0;
}
sum += help[i];
if (hashMap.containsKey(sum - k)) {
len = Math.max(i - hashMap.get(sum - k), len);
}
if (!hashMap.containsKey(sum)) {
hashMap.put(sum, i);
}
}
return len;
}
衍生之最多异或和为0:
public static int zzzi_sumisit4(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
hashMap.put(0, -1);
int[] mosts = new int[arr.length];
int max = 0;
int cer = 0;
for (int i = 0; i < arr.length; i++) {
cer ^= arr[i];
if (hashMap.containsKey(cer)) {
int coco = hashMap.get(cer);
mosts[i] = coco == -1 ? 1 : mosts[coco] + 1;
}
if (i > 0) {
mosts[i] = Math.max(mosts[i - 1], mosts[i]);
}
hashMap.put(cer, i);
max = Math.max(max, mosts[i]);
}
return max;
}
实践题(摘自牛客网)
在o(n)下,求出给定数组中小于等于aim的最长的len长度:
运用的方法是:window方法,双指针,从后面开始往回推,形成一个块,可当作加速!!
public static int sumisit5(int[] arr, int aim) {
int[] index = new int[arr.length];
int[] end = new int[arr.length];
index[arr.length - 1] = arr[arr.length - 1];
end[arr.length - 1] = arr.length - 1;
for (int i = arr.length - 2; i >= 0; i--) {
if (index[i + 1] < 0) {
index[i] = index[i+1] + arr[i];
end[i] = end[i+1];
} else {
index[i] = arr[i];
end[i] = i;
}
}
int len = 0;
int sum = 0;
int right = 0;
for (int left = 0; left < arr.length; left++) {
while (right < arr.length && sum + index[right] <= aim) {
sum += index[right];
right = end[right] + 1;
}
sum -= right == left ? 0 : arr[left];
len = Math.max(len, right - left);
right = Math.max(right, left + 1);
}
return len;
}