Coding Interview:最长子数组问题(2)

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);
        }
    }

猜你喜欢

转载自blog.csdn.net/zhumingyuan111/article/details/80373229