二叉树系列---找到累加和为指定值的最长路径长度

题目

给定一颗二叉树和一个sum,二叉树节点值为整数,求累加和为sum的最大路径长度; 路径是指从某个节点往下,每次最多选择一个孩子节点或者不选择所形成的节点链;

思路

已知头结点head和给定值sum;求maxLen(maxLen保存最大路径长度,整个过程中,需要比较maxLen,所以设定maxLen为变量);

对于当前节点,求出头到该节点的累加和,并存入sumMap中;
判断在以该节点为结尾的情况下,累加和为规定值的最长路径长度(更新最大路径长度);

实现

package binary_tree;

import java.util.HashMap;
import java.util.Map;

/**
 * 给定一颗二叉树和一个sum,二叉树节点值为整数,求累加和为sum的最大路径长度;
 * 路径是指从某个节点往下,每次最多选择一个孩子节点或者不选择所形成的节点链;
 * @author fxx
 *
 */
public class MaxPathLenOfSumEqualsGivenValue {

    private int maxLen=0;

    /*
     * sumMap:保存从head开始的一条路径上的累加和;
     *        key:保存某个累加和;
     *        value:在这个累加和在路径中《最早》出现的层数
     * 对于当前节点,需要父节点的累加和+当前节点的值(所以需要先序遍历的变形应用)
     * 保证level为最早出现这个累加和的层数:
     *     sumMap中加入某个累加和时,判断是否已经有该累加和,没有了加入;有不加入;
     *     
     *  求解以每个节点结尾的情况下,累加和为规定值的最长路径长度;
     */
    public int getMaxLen(Node head,int sum){
        Map<Integer,Integer> sumMap=new HashMap<Integer,Integer>();
        sumMap.put(0, 0);
        return preOrder(head,sum,0,1,sumMap);       
    }

    private int preOrder(Node head, int sum, int preSum, int level,Map<Integer, Integer> sumMap) {
        if(head==null){
            return maxLen;
        }
        int curSum=preSum+head.value;

        if(!sumMap.containsKey(curSum)){  //保证level为最早出现这个累加和的层数
            sumMap.put(curSum, level);
        }

        //求解以每个节点结尾的情况下,累加和为规定值的最长路径长度,更新最大路径长度
        if(sumMap.containsKey(curSum-sum)){ 
            maxLen=Math.max(maxLen, level-sumMap.get(curSum-sum));
        }

        //遍历左右子树
        preSum=curSum;
        preOrder(head.left,sum,preSum,level+1,sumMap);
        preOrder(head.right,sum,preSum,level+1,sumMap);


        //返回之前,如果当前累加和是新加入的(通过level判断),则删除
        if(level==sumMap.get(curSum)){
            sumMap.remove(curSum);
        }

        return maxLen;
    }

}

测试

/**
     * @param args
     */
    public static void main(String[] args) {
        MaxPathLenOfSumEqualsGivenValue MS=new MaxPathLenOfSumEqualsGivenValue();
        Node head=MS.buildTree();
        //int maxLen=MS.getMaxLen(head,-9);
        int maxLen=MS.getMaxLen(head,6);
        System.out.println(maxLen);
    }

    private Node buildTree(){
        Node head=new Node(-3);
        head.left=new Node(3);
        head.right=new Node(-9);

        head.left.left=new Node(1);
        head.left.right=new Node(0);

        head.right.left=new Node(2);
        head.right.right=new Node(1);

        head.left.right.left=new Node(1);
        head.left.right.right=new Node(6);

        return head;
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值