美文网首页
二叉树任意两节点之间的最短路径

二叉树任意两节点之间的最短路径

作者: Katakuly | 来源:发表于2018-09-01 18:43 被阅读0次
    二叉树.jpg
    对于上图所示二叉树,2和8的最短路径是2,8和6的最短路径是5。
    二叉树中求任意两个节点的最短路径可以分为以下三步:
    1.求出两个节点的最近公共祖先root(这个可以参考我另一篇文章https://www.jianshu.com/p/3989c663e26d
    2.利用深度搜索分别求出node1和node2到root的路径
    3.对两个路径长度求和即得所求
    import java.util.ArrayList;
    
    class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    
    public class Solution{
        public static TreeNode lowestCommonAncestor (TreeNode root,TreeNode node1,TreeNode node2){
            if (root==null || root==node1 || root==node2) {
                return root;
            }
            //采用递归调用的思路,将二叉树分为左子树和右子树分别处理
            //使用递归需要注意两点:
            //1.子问题需与原始问题为同样的问题,且更为简单;2.不能无限制地调用本身,程序必须有出口
            //查看左子树中是否有目标结点,没有为null
            TreeNode left = lowestCommonAncestor(root.left,node1,node2);
            //查看右子树是否有目标节点,没有为null
            TreeNode right = lowestCommonAncestor(root.right, node1, node2);
            //都不为空,说明做右子树都有目标结点,则公共祖先就是本身
            if((left==node1 && right==node2 ) || (left==node2 && right==node1)) { 
                return root;
            }
            return left==null?right:left; 
        }
    
        /**
         *  获取某一节点至其某祖先节点的路经
         */
        public static boolean getPath(TreeNode root,TreeNode target,ArrayList<TreeNode> pathList){
            if (root==target) 
                return true;
            pathList.add(root);
            boolean hasFound=false;
            if (root.left!=null)
                hasFound=getPath(root.left,target,pathList);
            if (!hasFound && root.right!=null)
                hasFound=getPath(root.right,target,pathList);
            if (!hasFound)
                pathList.remove(pathList.size()-1);
            return hasFound; 
        }
    
        public static int getLength(TreeNode root,TreeNode node1,TreeNode node2){
            ArrayList<TreeNode> pathList1=new ArrayList<>();
            ArrayList<TreeNode> pathList2=new ArrayList<>();
            //求出两个节点的最近公共祖先
            TreeNode ancestor=lowestCommonAncestor(root,node1,node2);
            //分别求出公共祖先到两个节点的路经长
            int l1=getPath(ancestor,node1,pathList1);
            int l2=getPath(ancestor,node2,pathList2);
            return (l1+l2);
        }
    
        public static void main(String[] args) {
            TreeNode root=new TreeNode(1);
            TreeNode node2=new TreeNode(2);
            TreeNode node3=new TreeNode(3);
            root.left=node2;
            root.right=node3;
            TreeNode node4=new TreeNode(4);
            TreeNode node5=new TreeNode(5);
            node2.left=node4;
            node2.right=node5;
            TreeNode node6=new TreeNode(6);
            TreeNode node7=new TreeNode(7);
            node3.left=node6;
            node3.right=node7;
    
            ArrayList<TreeNode> pathList1=new ArrayList<TreeNode>();
            ArrayList<TreeNode> pathList2=new ArrayList<TreeNode>();
            getPath(root,node5,pathList1);
            getPath(root,node2,pathList2);
            int res=pathList1.size()+pathList2.size();
            System.out.println(res);
            // for (TreeNode treeNode:pathList)
            //  System.out.println(treeNode.val);
        }
    }
    

    相关文章

      网友评论

          本文标题:二叉树任意两节点之间的最短路径

          本文链接:https://www.haomeiwen.com/subject/xqwywftx.html