zoukankan      html  css  js  c++  java
  • 最近公共祖先

    leetcode 美团笔试也考到了就是要找二叉树两个节点的第一个共同的祖先。对于树,没有规定,不一定是一颗二叉查找树。

    第一种情况:首先 如果这个树是一个二叉树的,并且是一颗二叉查找树的话

    由于二叉查找树的左子树节点比父节点小,右子树节点比父节点大,则输入两个节点,只用从根节点开始比较,如果,如果当前节点比这两个节点都大,则最低的公共父节点一定在左子树中,那么遍历左子树节点。如果当前节点比两个节点小,那么遍历右子节点。这样,找到的第一个值在二者之间的节点就是公共的最低的祖先。

    代码如下:(在leetcode的ac代码)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) {
            if(node1.val>node2.val){
                TreeNode temp = node1;
                node1 = node2;
                node2 =temp;
            }
            if(root==null||root==node1||root==node2) return root;
            if(node1.val<root.val&&node2.val>root.val) return root;
            else if(node1.val<root.val&&node2.val<root.val) return lowestCommonAncestor(root.left,node1, node2);
            else  return lowestCommonAncestor(root.right,node1, node2);
            
            
        }
    }

    第二种情况:如果只是一般的二叉树,不是搜索树的话 可以用递归的方法:方法思路如下:收下看root是否为公共祖先,不是的话,则递归到左右节点(可能效率不怎么好)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if(root==null||root==p||root==q) return root;
            TreeNode left = lowestCommonAncestor(root.left,p,q);
            TreeNode right =lowestCommonAncestor(root.right,p,q);
            if(left!=null&&right!=null) return root;
            return left!=null?left:right;
        }
    }

    第三种 如果这个就是一个一般的树  亦不一定是二叉树。如何处理?思路就是找出这两个节点的路径,并存在链表中,则这两个链表的交点就是最低公共祖先

    实现如下:

        /*-------------------第二种情况--------------------------------------------*/
        //如果这个树只是一个一般的树 也不一定是是二叉树。这里当做二叉树来处理吧。不是二叉树的情况也一样的方法。
        
        public TreeNode fin_nearances3(TreeNode node1,TreeNode node2,TreeNode root){
            if(root==null||node1==root||node2==root) return root;
            List<TreeNode> path1 = new ArrayList<>();
            List<TreeNode> path2 = new ArrayList<>();
            
            
            findpath(root, node1, path1);
            findpath(root,node2,path2);
            return findlastcommonNode(path1, path2);
        }
        //找出节点P的路径 存在path中,如果不存在的话就返回false
        public boolean findpath(TreeNode root,TreeNode p,List<TreeNode> res){
            if(root==p) {
                res.add(root);
                return true;
            }
            
            res.add(root);
            boolean found = false;
            found = findpath(root.left, p, res);
            found = findpath(root.right, p, res);
            if(!found) res.remove(res.size()-1);
            return found;
            
            
        }
        //找出两个path的最后一个公共的节点
        public TreeNode findlastcommonNode(List<TreeNode> path1,List<TreeNode> path2){
            TreeNode res = null;
            int i=0;
            while(i<path1.size()&&i<path2.size()){
                if(path1.get(i)==path2.get(i))
                    res = path1.get(i);
                i++;
            }
            
            return res;
        }

    //如果只是普通的树  不一定是二叉树 但是节点中有指向父节点的指针。这样将问题转化为两个链表的第一个交点。

    贴一下此博主的解法:

    http://blog.csdn.net/xyzbaihaiping/article/details/52122885

  • 相关阅读:
    Android -- 保存文件
    Android -- AsyncTask
    Java 集合
    Android -- ViewPager放入多个XML监听每个的控件
    Android -- 自定义标题栏,背景颜色填充满
    PowerShell正则表达式(一) 定义模式
    PowerShell 简单模式识别 1
    Powershell 设置数值格式 1
    PowerShell String对象方法 1
    PowerShell 字符串操作符
  • 原文地址:https://www.cnblogs.com/CongLollipop/p/6601493.html
Copyright © 2011-2022 走看看