求二叉树根节点到指定节点的路径

算法 求二叉树根节点到指定节点的路径

@author:Jingdai
@date:2020.11.05

题目描述

给你一个棵二叉树,再给你一个指定的节点,求根节点到指定节点的路径。

在这里插入图片描述

如图,比如让你求到 4 节点的路径,则应该返回的路径为 [0, 1, 4]

思路

利用二叉树的先序遍历,寻找指定的节点,同时用一个栈 stack 记录遍历到的节点,当找到需要的节点后立即返回结果。但是这样有一个问题,就是在遍历中 stack 记录的路径中包含一些其他的节点,比如要求上图中到 4 节点的路径,则遍历到 4 节点时,stack 中的路径就为 [0, 1, 3, 5, 6, 7, 8, 4],而需要的路径为 [0, 1, 4] ,中间多了许多不需要的节点。

为了去掉 stack 中不需要的节点,需要在递归查找过程中进行回溯,pop 这些不需要的节点。先序遍历查找是先看根节点是否满足要求、若不满足要求再去左子树和右子树中去查找,如果右子树还是找不到,说明该节点不在路径中,需要弹出该节点。

综上,代码片段如下:

public static boolean getPathToTarget(TreeNode node, TreeNode target, 
	LinkedList<TreeNode> path) {
    
    
    if (node == null) 
        return false;

    path.push(node);

    if (node == target)
        return true;
    // find in left tree
    if (getPathToTarget(node.left, target, path)) 
        return true; 
    // find in right tree
    if (getPathToTarget(node.right, target, path))
        return true;

    // this node is not in the path of target
    // cause leftchild rightchild and itself do not have target node
    path.pop();
    return false;
}

为了测试整个代码的正确性,使用LeetCode 定义的 TreeNode 来建立树,然后进行测试,完整的代码如下。

代码

import java.util.*;

public class Solution {
    
    

    public static void main(String[] args) {
    
    

        // create tree
        TreeNode root = new TreeNode(0);
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        TreeNode node8 = new TreeNode(8);
        root.left = node1;
        root.right = node2;
        node1.left = node3;
        node1.right = node4;
        node3.left = node5;
        node3.right = node6;
        node6.left = node7;
        node6.right = node8;

        // test
        LinkedList<TreeNode> path = new LinkedList<>();
        // get the path to node4
        boolean hasPath = getPathToTarget(root, node4, path);
        if (hasPath) {
    
    
            for (TreeNode node : path) {
    
    
                System.out.print(node.val + " ");
            }
        }
        System.out.println();
        System.out.println("============");
        path.clear();
        // get the path to nonexistent node
        hasPath = getPathToTarget(root, new TreeNode(9), path);
        if (hasPath) {
    
    
            for (TreeNode node : path) {
    
    
                System.out.print(node.val + " ");
            }
        }

    }

    public static boolean getPathToTarget(TreeNode node, TreeNode target, 
        LinkedList<TreeNode> path) {
    
    
        if (node == null) 
            return false;

        path.push(node);

        if (node == target)
            return true;
        // find in left tree
        if (getPathToTarget(node.left, target, path)) 
            return true; 
        // find in right tree
        if (getPathToTarget(node.right, target, path))
            return true;

        // this node is not in the path of target
        // cause leftchild rightchild and itself do not have target node
        path.pop();
        return false;
    }
}

class TreeNode {
    
    
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) {
    
     val = x; }
}

猜你喜欢

转载自blog.csdn.net/qq_41512783/article/details/109516464
今日推荐