栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

二叉树最近的公共祖先[后序遍历与回溯模型的考察]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉树最近的公共祖先[后序遍历与回溯模型的考察]

后序遍历与回溯
  • 前言
  • 一、二叉树最近的公共祖先
  • 二、直接法 & 回溯模型
    • 1、直接法
    • 2、回溯模型(合并if)
  • 总结
  • 参考文献

前言

二叉树问题都可分类于,前序与dfs/中序与平衡二叉/后序与回溯/层序与bfs。二叉树最近的公共祖先,用回溯时寻找到的祖先体现为最近祖先。

一、二叉树最近的公共祖先

二、直接法 & 回溯模型 1、直接法

按后序遍历的节点顺序,以每个节点作为root,寻找左右节点,当两个都找到了则该root为最近公共祖先。

// 二叉树的最近公共祖先。
public class LowestCommonAncestor {
    // 按后序遍历的节点顺序,以每个节点作为root,寻找左右节点,当两个都找到了则该root为最近公共祖先。
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return null;

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        if (left != null) return left;
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (right != null) return right;

        flag1 = flag2 = false;
        order(root, p, q);
        return flag1 && flag2 ? root : null;
    }

    boolean flag1, flag2;// 标记两个是否都找到了。

    private void order(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return;
        if (root == p) flag1 = true;
        if (root == q) flag2 = true;

        order(root.left, p, q);
        order(root.right, p, q);
    }

    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
}
2、回溯模型(合并if)

利用回溯时判定左右两边是否都找到了。(后序遍历与回溯模型的考察。)

两种情况,p/q有一个作为它们俩的最近公共祖先;有个root的左右子树上挂着p/q;

第一种情况:率先找到那个就是它俩公共祖先;第二种情况:回溯时左右子树都找到了,返回root即可。

注:左子树找到了root,就不用再遍历右边的所有右子树了,这部分可以剪枝。

// 利用回溯时判定左右两边是否都找到了。(后序遍历与回溯模型的考察。)
// 两种情况,p/q有一个作为它们俩的最近公共祖先;有个root的左右子树上挂着p/q;
// 第一种情况:率先找到那个就是它俩公共祖先;第二种情况:回溯时左右子树都找到了,返回root即可。
// 注:左子树找到了root,就不用再遍历右边的所有右子树了,这部分可以剪枝。
class LowestCommonAncestor2 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || isFind) return null;// 剪枝。
        if (root == p || q == root) return root;

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        // 一个在左,一个在右,root就是最近公共祖先。
        if (left != null && right != null) {
            isFind = true;

            return root;
        }
        return left != null ? left : right;
    }

    boolean isFind = false;// 找到了设个标记,方便剪枝。


    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
总结

1)二叉树问题,莫过于前序与dfs/中序与平衡二叉/后序与回溯/层序与bfs。
2)9个月前写的回溯模型,回溯时有left/right是否为null的四种情况判定,意味着4个if,现在很容易就把if合并,写出更简洁的代码,所以要多练才会灵活,思路才能打开 & 寻找到联系之处。

参考文献

[1] LeetCode 二叉树最近的公共祖先

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1035144.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号