剑指 Offer 68 - II. 二叉树的最近公共祖先

题目:

剑指 Offer 68 - II. 二叉树的最近公共祖先
236. 二叉树的最近公共祖先
在这里插入图片描述

题解:

1. 题解一:递归

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 题解二:非递归

/**
 * 思路(非递归):
 * 1、找到root->p的路径
 * 2、找到root->q的路径
 * 3、两条路径求最后一个相交节点, 即为公共节点
 * 
 * 就是前序遍历根节点到p和到q的两个路径(注意剪枝) 然后两个路径逐个比对,最后一个相同的节点即为公共节点。
 */

代码:

该题代码无法用原来的方式进行本地测试。(LeetCode后台对 “结点相等” 已进行处理)

1. 疑难点一:
在这里插入图片描述
2. 疑难点二:
在这里插入图片描述

1. 代码一:递归

public class 面试题68_2 {

    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) // 当越过叶节点,则直接返回 null
        {
            return null;
        }
        if(root == p || root == q) // 当 root 等于 p, q,则直接返回 root ;
        {
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q); // 开启递归左子节点,返回值记为 left ;
        TreeNode right = lowestCommonAncestor(root.right, p, q); // 开启递归右子节点,返回值记为 right ;
        if(left == null && right == null) // 1.
        {
            return null;
        }
        if(left == null) // 3.
        {
            return right;
        }
        if(right == null) // 4.
        {
            return left;
        }
        return root; // 2. if(left != null && right != null)
    }

    public static void main(String[] args) {
        // Integer nums[] = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
        // TreeNode root = ConstructTree.constructTree(nums);
        // TreeOperation.show(root);

        // System.out.println("***************************************");

        // TreeNode p1 = new TreeNode(5);
        // TreeNode q1 = new TreeNode(1);
        // TreeNode res1 = lowestCommonAncestor(root, p1, q1);
        // System.out.println(res1.val);

        // System.out.println("***************************************");

        // TreeNode p2 = new TreeNode(5);
        // TreeNode q2 = new TreeNode(4);
        // TreeNode res2 = lowestCommonAncestor(root, p2, q2);
        // System.out.println(res2.val);

        TreeNode root = new TreeNode(1);
        TreeNode right = new TreeNode(2);
        root.right = right;
        TreeNode left = new TreeNode(3);
        root.left = left;
        TreeOperation.show(root);

        System.out.println("***************************************");
        
        TreeNode res = lowestCommonAncestor(root, left, right);
        System.out.println(res.val);
    }
}

2. 代码二:非递归

import java.util.*;

public class 面试题68_2 {

    // 方法2:非递归
    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || p == root || q == root)
        {
            return root;
        }

        List<TreeNode> pPath = findPath(root, p); // 找到root->p的路径
        List<TreeNode> qPath = findPath(root, q); // 找到root->q的路径

        TreeNode common = null;

        for(int i = 0, j = 0; i < pPath.size() && j < qPath.size(); i++, j++)
        {
            if(pPath.get(i) == qPath.get(j))
            {
                common = pPath.get(i); // 两条路径求最后一个相交节点, 即为公共节点
            }
        }

        return common;
    }

    public static List<TreeNode> findPath(TreeNode root, TreeNode node)
    {
        List<TreeNode> path = new ArrayList<>();
        dfs(root, node, new ArrayList<>(), path);
        return path;
    }

    public static void dfs(TreeNode root, TreeNode node, List<TreeNode> tmp, List<TreeNode> path)
    {
        if(root == null)
        {
            return;
        }

        tmp.add(root);

        if(root == node)
        {
            path.addAll(new ArrayList<>(tmp));
        }

        dfs(root.left, node, tmp, path);
        dfs(root.right, node, tmp, path);

        tmp.remove(tmp.size() - 1);
    }

    public static void main(String[] args) {
        // Integer nums[] = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
        // TreeNode root = ConstructTree.constructTree(nums);
        // TreeOperation.show(root);

        // System.out.println("***************************************");

        // TreeNode p1 = new TreeNode(5);
        // TreeNode q1 = new TreeNode(1);
        // TreeNode res1 = lowestCommonAncestor(root, p1, q1);
        // System.out.println(res1.val);

        // System.out.println("***************************************");

        // TreeNode p2 = new TreeNode(5);
        // TreeNode q2 = new TreeNode(4);
        // TreeNode res2 = lowestCommonAncestor(root, p2, q2);
        // System.out.println(res2.val);

        TreeNode root = new TreeNode(1);
        TreeNode right = new TreeNode(2);
        root.right = right;
        TreeNode left = new TreeNode(3);
        root.left = left;
        TreeOperation.show(root);

        System.out.println("***************************************");
        
        TreeNode res = lowestCommonAncestor(root, left, right);
        System.out.println(res.val);
    }
}

参考:

  1. 面试题68 - II. 二叉树的最近公共祖先(后序遍历 DFS ,清晰图解)
  2. java代码递归和非递归图文详解
  3. 简单易懂,详解如下
  4. 最近公共祖先问题
  5. 二叉树的最近公共祖先
  6. 【C++ 经典递归】思路非常好理解 时间复杂度O(n), 空间复杂度O(n)
  7. 236. 二叉树的最近公共祖先(后序遍历 DFS ,清晰图解)
  8. 【236. 二叉树的最近公共祖先】简洁代码
  9. java代码递归和非递归图文详解
  10. JAVA DFS + 剪枝 9ms,92.44%
  11. 详细通俗的思路分析,多解法
  12. leetcode 二叉树的最近公共祖先(Java)
©️2020 CSDN 皮肤主题: 撸撸猫 设计师: 设计师小姐姐 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值