字节跳动后端开发开发者生态一面算法题思考

字节跳动后端开发开发者生态一面算法题思考

算法题:

给定一个二叉树和一个值sum*,请找出所有的根节点到叶子节点的节点值之和等于sum* 的路径,
例如:
给出如下的二叉树sum=22,

img

返回
[
[5,4,11,2],
[5,8,9]
]

1、思考历程

1、实现一个算法判断一个二叉树的叶子节点数量

/**
*1、如何判断一个节点是叶子节点<-->该节点非空,并且该节点的左右节点都为null,那么这个节点就是叶子节点
*/
public int countLeaf(){
    return countLeaf(root);
}
private int countLeaf(Node root) {
    if(root==null) return 0;
    if(root.left==null&&root.right==null) return 1;
    return countLeaf(root.left)+countLeaf(root.right);
}

2、实现一个算法,查找从根节点到叶子节点的路径,并判断这些和是否等于目标值

    /**
     * 判断从根节点到叶子节点的数值和为num的个数
     * @param num
     * @return
     */
    public int countEqualsPath(int num){
        return countEqualsPath(root,num);
    }

    private int countEqualsPath(Node root, int num) {
        if(root==null) return 0;
        if(root.right==null&&root.left==null){
            if(num==(int)root.e){
                return 1;
            }else {
                return 0;
            }
        }
        num = num-(int)root.e;
        return countEqualsPath(root.right,num)+countEqualsPath(root.left,num);
    }

思路:

1、从一个二叉树的根节点出发到叶子节点的该条路径的总和为一个目标值,可以看到,一定是从根节点出发,从叶子节点结束才是一条完整的路径,根节点只有一个,而叶子节点有多个,那么这里涉及到一个判断叶子节点的问题,叶子节点是没有子节点的节点,当节点本身不为null,并且其没有左右节点,那么该节点就是叶子节点

2、如何判断这条路径的总和等于num?笔者在无限思想风暴之中,突然冒出一个灵感,对于某一个特定的路径 如果num = 节点1+节点2+… 那么节点2+节点3+…=num-节点1 … ,那么每遍历一个节点,就将这个节点的权存入,当到达一个叶子节点的时候,如果叶子节点=num-前面遍历过的节点,那么可以认为这条路径上面的总和是等于num的,第二个问题就解决了

3、然后是怎么把一条路径上的数值存储如ArrayList中去呢?可以说,一个二叉树从根结点出发到叶子节点,具有相同父节点的子节点他们前面的路径一定是相同的,那么这样的话可以将前面的相同路径中的权递归地传入下一个节点中,一直传到叶子节点,当这个叶子节点满足条件后,就把这个ArrayList加入到之前定义好地队列中

2、算法实现

public ArrayList<ArrayList<Integer>> pathSum(TreeNode root,int num){
        ArrayList<ArrayList<Integer>> path = new ArrayList<>();
        getPathSum(root,path,num);
        return path;
    }

    private void getPathSum(TreeNode root, ArrayList<ArrayList<Integer>> path,int num) {
        if(root==null) return;
        ArrayList<Integer> temps = new ArrayList<>();
        num = num-root.val;
        temps.add(root.val);
        getPathSum(root.left,path,temps,num);
        getPathSum(root.right,path,temps,num);
        return;
    }

    private void getPathSum(TreeNode root, ArrayList<ArrayList<Integer>> path, ArrayList<Integer> temps, int num) {
        if(root==null) return;
        ArrayList<Integer> temp = new ArrayList<>(temps);
        temp.add(root.val);
        if(root.left==null&&root.right==null){
            if(num==root.val){
                path.add(temp);
            }
        }
        num = num-root.val;
        getPathSum(root.left,path,temp,num);
        getPathSum(root.right,path,temp,num);
    }

算法是思考过程,有小伙伴还有更好的方法的话,欢迎一起讨论啊~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值