程序员代码面试指南第二版 125.未排序数组中累加和为给定值的最长子数组长度
题目描述
给定一个无序数组arr, 其中元素可正、可负、可0。给定一个整数k,求arr所有子数组中累加和为k的最长子数组长度
输入描述:
第一行两个整数N, k。N表示数组长度,k的定义已在题目描述中给出
第二行N个整数表示数组内的数
输出描述:
输出一个整数表示答案
示例1
输入
5 0
1 -2 1 1 1
输出
3
第一次做; 核心:sum的含义:子数组arr[i,j]的累加和; a-b=k等价于a-k=b; 哈希表中只记录前缀和最早出现的索引; 为了记录arr[0,i]这个子数组的情况,需要先往哈希表中插入(0,-1)这个记录, 这样当sum=k时,也就是sum-k=0时,能够获取子数组arr[0,i]的长度
import java.util.Scanner;
import java.util.HashMap;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
int n = Integer.parseInt(str[0]);
int k = Integer.parseInt(str[1]);
str = sc.nextLine().split(" ");
int[] arr = new int[n];
for(int i=0; i<n; i++){
arr[i] = Integer.parseInt(str[i]);
}
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0, -1);
int sum = 0, len=0;
for(int i=0; i<n; i++){
sum = sum + arr[i];
if(map.containsKey(sum-k)){
len = Math.max(len, i-map.get(sum-k));
}
if(!map.containsKey(sum))
map.put(sum,i);
}
System.out.print(len);
}
}
125补充题1
题目描述
给定一个无序数组arr,其中元素可正、可负、可0。求arr所有子数组中正数与负数个数相等的最长子数组的长度。
[要求]
时间复杂度为O(n),空间复杂度为O(n)
输入描述:
第一行一个整数N,表示数组长度
接下来一行有N个数表示数组中的数
输出描述:
输出一个整数表示答案
示例1
输入
5
1 -2 1 1 1
输出
2
第一次做; 把正数看成1, 负数看成-1, 0不变, 还是求累加和, 正数个数和负数个数相等,也就是k=0; 个数相等问题转换成累加和,进而使用哈希表前缀和方法, 提前明确k的值
import java.util.Scanner;
import java.util.HashMap;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
int n = Integer.parseInt(str[0]);
str = sc.nextLine().split(" ");
int[] arr = new int[n];
for(int i=0; i<n; i++){
arr[i] = Integer.parseInt(str[i]);
}
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0, -1);
int sum = 0, len=0;
for(int i=0; i<n; i++){
if(arr[i]>0)
sum = sum + 1;
else if(arr[i]<0)
sum = sum - 1;
if(map.containsKey(sum)){
len = Math.max(len, i-map.get(sum));
}
if(!map.containsKey(sum))
map.put(sum,i);
}
System.out.print(len);
}
}
125补充题2
题目描述
给定一个无序数组arr,其中元素只能是1或0。求arr所有的子数组中0和1个数相等的最长子数组的长度
[要求]
时间复杂度为O(n),空间复杂度为O(n)
输入描述:
第一行一个整数N,表示数组长度
接下来一行有N个数表示数组中的数
输出描述:
输出一个整数表示答案
示例1
输入
5
1 0 1 0 1
输出
4
第一次做; 核心:个数相等问题转换成累加和, 进而用哈希表前缀和解决
import java.util.Scanner;
import java.util.HashMap;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
int n = Integer.parseInt(str[0]);
str = sc.nextLine().split(" ");
int[] arr = new int[n];
for(int i=0; i<n; i++){
arr[i] = Integer.parseInt(str[i]);
}
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0, -1);
int sum = 0, len=0;
for(int i=0; i<n; i++){
if(arr[i]==0)
sum = sum - 1;
else
sum = sum + 1;
if(map.containsKey(sum)){
len = Math.max(len, i-map.get(sum));
}
if(!map.containsKey(sum))
map.put(sum,i);
}
System.out.print(len);
}
}