二叉树系列——二叉树中任意两个节点之间的最短路径

来源:https://segmentfault.com/a/1190000003465753


题目:给定一棵二叉树的根节点和两个任意节点,返回这两个节点之间的最短路径


思路:两个节点之间的最短路径一定会经过两个节点的最小公共祖先,所以我们可以用LCA(最低公共祖先)的解法。不同于LCA的是,我们返回不只是标记,而要返回从目标结点递归回当前节点的路径。当遇到最小公共祖先的时候便合并路径。需要注意的是,我们要单独处理目标节点自身是最小公共祖先的情况。


Java代码实现如下:

public LinkedList<TreeNode> helper(TreeNode n, TreeNode p, TreeNode q){
    if(n == null){
        return null;
    }
    
    LinkedList<TreeNode> left = helper(n.left, p, q);
    LinkedList<TreeNode> right = helper(n.right, p, q);
    
    // 当左右都为空时
    if(left == null && right == null){
        // 如果当前节点是目标节点,开启一条新路径
        if(n == p || n == q){
            LinkedList l = new LinkedList<TreeNode>();
            l.add(n);
            return l;
        } else {
        // 否则标记为空
            return null;
        }
    // 如果左右节点都不为空,说明是最小公共祖先节点,合并两条路径
    } else if(left != null && right != null){
        finalPath.addAll(left);
        finalPath.add(n);
        Collections.reverse(right);
        finalPath.addAll(right);
        return left;
    // 如果当前节点是目标结点,且某一个子树不为空时,说明最小公共祖先是节点自身
    } else if (left != null){
        left.add(n);
        if(n == p || n == q){
            finalPath.addAll(left);
        }
        return left;
    } else {
        right.add(n);
        if(n == p || n == q){
            finalPath.addAll(right);
        }
        return right;
    }
}



  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用深度优先搜索(DFS)来遍历二叉树,记录每个叶子节点到根节点路径。具体步骤如下: 1. 定义一个栈,用于存储遍历过程节点路径。 2. 将根节点入栈,并将根节点的值加入路径。 3. 当栈不为空时,弹出栈顶节点,如果该节点是叶子节点,则输出路径。 4. 如果该节点有右子节点,则将右子节点入栈,并将右子节点的值加入路径。 5. 如果该节点有左子节点,则将左子节点入栈,并将左子节点的值加入路径。 6. 重复步骤3-5,直到栈为空。 代码实现如下: ``` class TreeNode: def __init__(self, val=, left=None, right=None): self.val = val self.left = left self.right = right def print_leaf_to_root_path(root): if not root: return stack = [(root, [root.val])] while stack: node, path = stack.pop() if not node.left and not node.right: print('->'.join(str(val) for val in path[::-1])) if node.right: stack.append((node.right, path + [node.right.val])) if node.left: stack.append((node.left, path + [node.left.val])) ``` 其,TreeNode是二叉树节点的定义,print_leaf_to_root_path是输出每个叶子节点到根节点路径的函数。函数,stack存储的是节点路径的元组,每次弹出栈顶元素时,如果该节点是叶子节点,则输出路径;否则,将其左右子节点入栈,并更新路径。最后,路径需要反转输出,因为我们是从叶子节点往根节点遍历的。 ### 回答2: 输出二叉树每个叶子节点到根节点路径是一道比较基础的二叉树深度遍历问题。通常可以通过深度优先搜索来解决。具体步骤如下: 1. 定义一个字符数组path,用于存储当前遍历到的路径; 2. 从根节点开始遍历二叉树,每次递归进入子节点时,将该节点的值添加到path数组末尾; 3. 如果当前节点是叶子节点,则将path数组的值依次输出,即得到该叶子节点到根节点路径; 4. 如果当前节点不是叶子节点,则继续递归遍历其左右子树; 5. 遍历完一个节点的左右子树后,需要将path数组末尾的值删除,回到当前节点的父节点上。 具体实现,需要注意以下问题: 1. 需要定义一个全局变量results,用于存储所有叶子节点到根节点路径; 2. path数组需要在每次递归时重新创建,以免不同叶子节点路径被重复输出; 3. 每次输出path数组的值时,需要在输出之前判断该节点是否为叶子节点,避免将非叶子节点的值输出。 整体思路和具体实现步骤如上所述,通过深度优先搜索,可以输出二叉树每个叶子节点到根节点路径。 ### 回答3: 二叉树是一种常见的数据结构,在计算机领域被广泛应用。输出二叉树每个叶子节点到根节点路径是二叉树遍历的一种常见操作,下面我将介绍一种简单的方法来实现这一操作。 首先是如何遍历二叉树。二叉树遍历有三种方式:前序遍历、序遍历和后序遍历。前序遍历指先访问根节点,然后遍历左子树和右子树;序遍历指先遍历左子树,然后访问根节点,最后遍历右子树;后序遍历指先遍历左子树,然后遍历右子树,最后访问根节点。这三种遍历方式的不同之处在于访问根节点的时间点不同。 接下来是输出每个叶子节点到根节点路径的过程。我们可以使用深度优先搜索(Depth-First Search)的方法来实现这一操作。当我们遍历到一个叶子节点时,记录下该节点所在的路径,然后回溯到它的父节点,继续遍历其它子节点。当遍历到根节点时,即可求出该叶子节点路径。 具体地,我们可以定义一个栈来记录已经访问过的节点,然后按照一定的顺序遍历二叉树。每遍历到一个非叶子节点,就将其入栈,然后继续遍历其左子树和右子树。当遍历到一个叶子节点时,将该节点所在的路径记录下来。然后将该节点弹出栈,并回溯到其父节点,继续遍历其它子节点。当遍历到根节点时,所有叶子节点路径都已经求出。 最后,我们需要注意一些特殊情况。例如,当二叉树为空时,无法输出任何路径。另外,某些节点可能没有左子树或右子树,这时不能直接访问它们的子节点,需要进行判断。 总的来说,输出二叉树每个叶子节点到根节点路径是一项比较基础的操作。我们可以利用深度优先搜索来实现这一操作。这种方法简单易懂,而且时间复杂度较低。对于一些特殊情况,需要进行额外的判断。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值