zoukankan      html  css  js  c++  java
  • 算法:二叉树公共父节点

    题目

    https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/

    题目

    思路1

    采用从上到下找当节点是不是p的父节点,然后反向遍历p的父节点,返回是不是q的父节点就行。

    代码1

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            /** 解法1:找出p所有的父节点,然后找出q所有的父节点。反向遍历能找到公共的子节点 */
            if (isParent(p , q) ) {
                return p;
            }
            if (isParent(q, p)) {
                return q;
            }
            
            List<TreeNode> parents = new ArrayList<TreeNode>();
            addParent(root, p,parents);
            for(int i = parents.size() -1 ; i >=0 ;i --) {
                TreeNode current = parents.get(i);
                if (isParent(current, q)) {
                    return current;
                }
            }
            for (int i = 0; i < parents.size();i ++) {
                System.out.println(parents.get(i).val);
            }
            return root;
        }
    
        private void addParent(TreeNode root, TreeNode target, List<TreeNode> parents) {
            if (isParent(root, target)) {
                parents.add(root);
            }
            if (root == null) {
                return;
            }
            addParent(root.left, target, parents);
            addParent(root.right, target, parents);
        }
    
        private boolean isParent(TreeNode parent, TreeNode child) {
            if (parent == null) {
                return false;
            }
            if (parent == child) {
                return true;
            }
            return isParent(parent.left,child) || isParent(parent.right, child);
        }
    }
    

    思路2

    如果有个节点是p,q的公共父节点节点,那么这个节点的子树一定包含分别包含p,q,或者说这个节点就是p,他左右子树里面包含q,或者这个节点是q他的子树包含p。

    代码2

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private TreeNode ans;
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            dfs(root, p, q);
            return ans;
        }
        private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
            if (root == null) {
                return false;
            }
            boolean lson = dfs(root.left, p, q); //是pq是否有个在左子树里面
            boolean rson = dfs(root.right, p, q); //pq是否有个在右子树里面
            if (lson && rson || (root.val == p.val || root.val == q.val) && (lson || rson)) {
                ans = root;
            }
            return lson || rson || (root.val == p.val || root.val == q.val); // 如果满足都在左或者都在右就是root是pq的公共子节点,不满足 lson || rson 要考虑一种特殊的情况,就是p是q的父节点。即p为Root
    
        }
    }
    

    题目: 二叉搜索树的公共父节点。

    二叉搜索树的性质,中序遍历的结果是从大到小的,也就是左子树的节点值始终比根节点小,右子树的值始终是比根节点的大。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if (root == null) {
                return null;
            }
            if (root.val < q.val && root.val < p.val) {
                return lowestCommonAncestor(root.right, p, q );
            } else if (root.val> q.val && root.val > p.val) {
                return lowestCommonAncestor(root.left, p, q );
            }
            return root;
        }
    }
    
  • 相关阅读:
    洛谷 P5564: [Celeste-B]Say Goodbye
    LOJ 3185: 「CEOI2018」斐波那契表示法
    Codeforces 749E: Inversions After Shuffle
    C#之在treeview中鼠标点击的所选的节点触发事件
    C#中选中指定文件并读取类似ini文件的内容
    免费的EmBitz可替代Keil MDK开发STM32、NXP项目
    C#创建子线程,子线程使用委托更新控件
    C#调用C++生成的动态链接库DLL
    C#之菜单控件、主窗体打开子窗体、GroupBox控件使用
    在Linux下用CANopenSocket协议模拟CAN总线通讯
  • 原文地址:https://www.cnblogs.com/lijunyzzZ/p/14225667.html
Copyright © 2011-2022 走看看