二叉树oj题解析

二叉树

二叉树的最近公共祖先

什么是最近公共祖先?

最近的公共祖先指的是这一棵树中两个节点中深度最大的且公共的祖先节点就是最近祖先节点。
也就是说这两个节点在树中距离最近的相交
例如:8 与6中的最近公共节点为2,因为他的最大深度就是2(在同一颗子树中)。
8与4的最近公共节点为3,因为他的最大深度是3(在左右两棵子树中的情况)。

leetcode中求二叉树中最近公共祖先

解题1.

公共祖先的三种形式:
1.题中可知:如果root根节点为q或者p,root这个节点就是最近的公共祖先节点。
2.如果p和q各自在原根节点的左右两棵子树中,则原根节点就是p和q的最近公共祖先。
3.如果p和q在根节点的同一颗子树中,则p和q的相遇之后两个节点最大深度且相交平行的第一个节点,就是最近公共祖先

java 复制代码
  public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)return null;
        //q或者p如果在其中的根节点上直接返回
       if(root==p||root==q)return root;
       //向左开始递归每一棵左右树
     TreeNode leftTree = lowestCommonAncestor(root.left,p,q);
    TreeNode rightTree= lowestCommonAncestor(root.right,p,q);
       //说明两棵树都不为null
       if(leftTree!=null&&rightTree!=null){
        return root;
       }else if(leftTree!=null){
        return leftTree;
       }else{
        return rightTree;
       }
    }
}

解题2.

前面我们也说过p和p两个节点的最大深度就是它两个的最近公共祖先,也就是相交的节点,这里的B就是它们两个的公共祖先。
那我们为什么不能将两个节点的以相同的距离开始走,最后两个节点的值相同就是最近公共祖先


假如两个节点到最近公共祖先的距离相同。
我们可以创建两个栈分别来存储到达p和q距离的所有节点,假设距离相同后pop出栈,如果出栈过程中两个节点的值相同就是它两个的公共祖先了。

这里我们如果遇到了多余的子树节点就返回false,并将其出栈,然后继续找p或者q节点找到后直接返回true。

java 复制代码
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)return null;
        Stack<TreeNode> stackP=new Stack<>();
        Stack<TreeNode> stackQ=new Stack<>();
        getTNodeLocation(root,stackP,p);
        getTNodeLocation(root,stackQ,q);
        //获取两个栈点的大小
        int sizeP=stackP.size();
        int sizeQ=stackQ.size();
        if(sizeP>sizeQ){
            int size = sizeP-sizeQ;
            while(size!=0){
                stackP.pop();
                size--;
            }
        }else{
            int size = sizeQ-sizeP;
           while(size!=0){
             stackQ.pop();
            size--;
           }
        }
        //找到两者的最近公共祖先
        while(!stackQ.isEmpty()&&!stackP.isEmpty()){
            if(stackQ.peek()==stackP.peek()){
                return stackQ.peek();
            }else{
                stackQ.pop();
                stackP.pop();
            }
        }
        return null;
    }
    //将指定的节点放入到栈中
    private boolean getTNodeLocation(TreeNode root,Stack stack,TreeNode t){
        //如果为null,返回给上一个节点false
        if(root==null)return false;
        stack.push(root);//走一步放入栈一个节点
        if(root==t)return true;//这里root如果为t直接返回
       boolean judg1 =  getTNodeLocation(root.left,stack,t);
       if(judg1==true)return true;
       boolean judg2 =  getTNodeLocation(root.right,stack,t);
       if(judg2==true)return true;
       stack.pop();//这里将出多余的节点出栈
       return false;
    }

根据二叉树创建字符串


这里的题意:对二叉树根节点进行前序的遍历,将遍历到的子树通过括号括起来,如果左子树有节点但是右子树没有节点,则将多余的右子树的括号省略,当右子树有节点但是左子树没有节点时,将左子树节点的括号添加进去。
这里的条件是:1.左子树如果为空,右子树不为空时,左右子树都有括号。
2.左子树不为空时,右子树为空,则可以忽略右树括号。

java 复制代码
   public String tree2str(TreeNode root) {
       StringBuilder sb=new StringBuilder();//通过StringBuilder来进行字符串的拼接
        tree2strChild(root,sb);
        return sb.toString();
    }
    public void tree2strChild(TreeNode root,StringBuilder sb){
        if(root==null)return ;
        sb.append(root.val);//将根节点放进去
        if(root.left!=null){
            sb.append("(");//左子树不为空加左括号
            tree2strChild(root.left,sb);
            sb.append(")");//左子树归时加右括号
        }else{
        //左树是空的,右树如果也为空就要加()
            if(root.right==null){
                return;
            }else{
                sb.append("()");
            }
        }
        if(root.right!=null){
            sb.append("(");
            tree2strChild(root.right,sb);
            sb.append(")");
        }else{
            return;
        }
    }

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=121ff85d13ss0

相关推荐
彧azz3 小时前
图的存储结构详解:邻接矩阵的原理、实现与应用
开发语言·数据结构·学习·php
IT_Octopus3 小时前
IntelliJ 本地日志路径自定义:`-DLOG_PATH=./logs` 为什么总“不听话“
java·log4j·intellij-idea
长征coder4 小时前
【无标题】
java·性能优化
新时代牛马4 小时前
PCI与PCIe 硬件原理、配置空间/BAR 与 Linux 驱动完整篇:从 LTSSM、TLP 到 ECAM 与probe
java·linux·服务器
Bs_MoneyMagnet5 小时前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
sunshine22 girl5 小时前
Java学习一 环境配置2 Idea的入门使用和maven配置,项目启动脚本配置
java·maven
有点。6 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
CRMEB系统商城7 小时前
CRMEB标准版系统(Java)v3.1正式发布
java·spring·微信小程序·php·教育电商
写后端的胖头鱼7 小时前
【高频面试题】Java 基础类型 + 包装类 + String 互相转换
java·开发语言
weixin_460443567 小时前
企业考试系统从.NET迁移到Java+Linux:数据库迁移、接口兼容与灰度切换实践
java·煤矿培训考试系统·煤矿在线考试系统·煤矿安全培训·煤矿考试系统·一人一档