1.未排序的数组中累加和为小于或者等于给定值的最长子数组长度
2.在二叉树中找到累加和为指定值的最长路径长度
问题1
令Subsum[j] 等于array{0…j}的累加和,则从0至j这部分中,最长子数组长度应为len = j-k; K为最先出现的SubSum[k]>=SubSum[j]-target 的位置。求最先出现的位置,我们需要辅助数组Fe.令Fe[i] = Max{Fe[i-1],SubSum[i]}.因此Fe为非递减数组,可以使用二分查找法。
下面给出代码
int getMaxLenLessEqualTarget(int[]array,int target){
if(array==null || array.length==0){
return 0;
}
int max = 0;
int[]fe = new int[array.length+1];
int sum = 0;
for(int i=0;i<array.length;i++){
sum+=array[i];
if(sum<=target){
max = Math.max(max,i+1);
}else{
int j = findIndex(fe,0,i,sum-target);
if(j<=i){
max = Math.max(max,i-j+1);
}
fe[i+1] = Math.max(fe[i],sum);
}
}
return max;
}
int findIndex(int[]array,int start,int end,int target){
if(start>end){
return start;
}
int mid = (start+end)/2;
if(array[mid]==target){
int i = mid;
while(array[--i]==target);
return i+1;
}else if(array[mid]>target){
return findIndex(array,start, mid-1,target);
}else{
return findIndex(array,mid+1,end,target);
}
}
问题2
方法类似最长子数组问题(1)中的解题思路,使用Map结构记录出现相关值的层次,需要注意的是当递归方法结束的时候如果KEY值出现在本层,需要将KEY移除。
static class Node{
int val;
Node left;
Node right;
Node(int val){
this.val = val;
}
}
private Map<Integer,Integer> map = new HashMap<>();
private int max = 0;
void dfs(Node root,int target,int level,int preSum){
if (root==null){
return;
}
int curSum = preSum+root.val;
if(curSum == target){
max = Math.max(max,level+1);
}
if(map.containsKey(curSum-target)){
max = Math.max(max,level-map.get(curSum-target)+1);
}
if(!map.containsKey(curSum)){
map.put(curSum,level);
}
dfs(root.left,target,level+1,curSum);
dfs(root.right,target,level+1,curSum);
if(map.get(curSum)==level){
map.remove(curSum);
}
}