[TOC]
思路;
维护一个前缀和。定义一个hashmap,遍历数组元素arr【i】。key表示从arr最左边开始累加的过程中出现过的sum的值,对应的value值则表示sum值最早出现的位置。
举例说明:
arr = {1,2,3,1,1,1,1,1,1,6,7,8},查找和为6的最长字数组的和。
map中的内容是;{0=-1, 1=0, 33=11, 3=1, 6=2, 7=3, 8=4, 9=5, 10=6, 11=7, 12=8, 18=9, 25=10}。其含义是:-1的位置和是0,0位置和是1,11的位置和是33。key的含义是到当前元素为止,和是多少。value的含义是当前元素的下标是多少。sum = 12,和sum = 6之间的差是6,对应下标之间的差值是8 - 2 = 6。所以,和为6的最长字数组长度是6.
代码:
public int MaxLength(int[] arr, int k){
if(arr == null || arr.length == 0)
return 0;
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(0, -1); //首先在map中放入0,1.表示在-1位置的时候,sum是0.
int len = 0;
int sum = 0;
for(int i = 0; i < arr.length; i++){
sum += arr[i]; //从0位置开始进行累加
//如果包含sum-k,则说明存在一个以arr[i]结尾的子串的和为k。
if(map.containsKey(sum-k)){
//令map.get(sum-k)为j,则j代表从j代表从左到右不断累加过程中,第一次出现sum-k这个累加和的位置。
//i-j就是子串长度
len = Math.max(i-map.get(sum-k), len);
}
if(!map.containsKey(sum)){
map.put(sum, i);
}
}
return len;
}