剑指offer 学习笔记 树中两个节点的最低公共祖先

2023-11-08

面试题68:树中两个节点的最低公共祖先。

可以先得到从根节点到这两个节点的路径,之后找出最后一个公共节点,代码中的树为:
在这里插入图片描述

#include <iostream>
using namespace std;

struct TreeNode {
    int m_nValue;
    vector<TreeNode*> m_chlidren;
};

bool GetNodePath(TreeNode* pRoot, TreeNode* pNode, vector<TreeNode*> &path) {
    if (pRoot == pNode) {
        return true;
    }

    bool found = false;
    path.push_back(pRoot);

    vector<TreeNode*>::iterator b = pRoot->m_chlidren.begin();
    while (!found && b != pRoot->m_chlidren.end()) {    
        found = GetNodePath(*b, pNode, path);
        ++b;
    }
    
    if (!found) {    // 以上循环结束时以pRoot为根节点的子树要么含pNode,要么不含,当不含时,将当前节点从路径中删除
        path.pop_back();
    }

    return found;
}

TreeNode* FindLastCommonNode(vector<TreeNode*> path1, vector<TreeNode*> path2) {
    vector<TreeNode*>::const_iterator b1 = path1.begin();
    vector<TreeNode*>::const_iterator b2 = path2.begin();

    TreeNode* res = nullptr;
    while (b1 != path1.end() && b2 != path2.end()) {
        if (*b1 != *b2) {
            return res;
        }
        res = *b1;
        ++b1;
        ++b2;
    }

    if (b2 == path2.end() && b1 == path1.end()) {
        return *(b1.end() - 1);
    }

    return nullptr;
}

TreeNode* FindLastCommonParent(TreeNode *pRoot, TreeNode *pNode1, TreeNode *pNode2) {
    if (pRoot == nullptr || pNode1 == nullptr || pNode2 == nullptr) {
        return nullptr;
    }

    vector<TreeNode*> path1;
    vector<TreeNode*> path2;
    GetNodePath(pRoot, pNode1, path1);
    GetNodePath(pRoot, pNode2, path2);

    return FindLastCommonNode(path1, path2);
}

int main() {
    TreeNode *Node1 = new TreeNode();
    TreeNode *Node2 = new TreeNode();
    TreeNode *Node3 = new TreeNode();
    TreeNode *Node4 = new TreeNode();
    TreeNode *Node5 = new TreeNode();
    TreeNode *Node6 = new TreeNode();
    TreeNode *Node7 = new TreeNode();
    TreeNode *Node8 = new TreeNode();
    TreeNode *Node9 = new TreeNode();
    TreeNode *Node10 = new TreeNode();
    
    Node1->m_nValue = 1;
    Node2->m_nValue = 2;
    Node3->m_nValue = 3;
    Node4->m_nValue = 4;
    Node5->m_nValue = 5;
    Node6->m_nValue = 6;
    Node7->m_nValue = 7;
    Node8->m_nValue = 8;
    Node9->m_nValue = 9;
    Node10->m_nValue = 10;

    Node1->m_chlidren.push_back(Node2);
    Node1->m_chlidren.push_back(Node3);
    Node2->m_chlidren.push_back(Node4);
    Node2->m_chlidren.push_back(Node5);
    Node4->m_chlidren.push_back(Node6);
    Node4->m_chlidren.push_back(Node7);
    Node5->m_chlidren.push_back(Node8);
    Node5->m_chlidren.push_back(Node9);
    Node5->m_chlidren.push_back(Node10);

    TreeNode* pRes = FindLastCommonParent(Node1, Node6, Node8);

    if (pRes) {
        cout << pRes->m_nValue << endl;
    } else {
        cout << "没有公共祖先。" << endl;
    }
}

以上解法不适合一个节点在另一个节点的路径上的情况。

相关题目:
1.如输入的树是二叉搜索树,可以从根节点开始比较值,如根节点值比两个数都大,那么最低公共祖先就在根节点的左子树中,如根节点值比这两个数都小,那么最低公共祖先就在根节点的右子树中,递归到一个节点值在两个输入的节点值之间时,这个节点就是结果。
2.如输入的树中有指向父节点的指针,那么从两个输入节点开始,各自向上直到根节点是两个链表,相当于找链表的第一个公共节点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

剑指offer 学习笔记 树中两个节点的最低公共祖先 的相关文章

随机推荐

  • chisel相比verilog优势之一:复用特性

    0 绪论 世界由于人这个最大的无厘头变量 还是比技术本身复杂难懂很多 各种技术的兴起与发展总是有其背后的理由的 这篇文章是这个系列的第三篇文章 主要来说明Chisel比Verilog在某些方面具有优势的理由 换句话说 为什么要用Chisel
  • S32DS IDE使用Tips--参考汽车电子expert成长之路

    目录 一 S32DS for Arm PA PEMicro系列调试器包括以下接口类型 1 如何创建在MCU应用工程中添加SDK 2 如何使用SDK的demo工程 3 如何查看SDK外设组件 Component 的帮助文档 4 S32DS 使
  • 网络--TCP/IP

    TCP IP 是供已连接因特网的计算机进行通信的通信协议 在 TCP IP 内部 TCP IP不是一个协议 而是一个协议族的统称 包含一系列用于处理数据通信的协议 TCP 传输控制协议 应用程序之间通信 UDP 用户数据包协议 应用程序之间
  • [软件工程]毕业设计选题软件

    1 分析文档 1 1软件功能概述 本系统由3个功能模块组成 分别是学生功能模块 教师功能模块 教务员功能模块 附加一个独立的高级查询模块 学生功能 l 学生可以在任何能够连接Internet的计算机登录到毕业设计选题系统中 l 学生可以在选
  • HBase分布式架构处理大数据量(高并发和实时处理)

    先来了解下Hadoop的简单原理 一 HDFS主要是用于做什么的 HDFS Hadoop Distributed File System 分布式文件管理系统 是Hadoop项目的核心子项目 是分布式计算中数据存储管理的基础 是基于流数据模式
  • (董付国)Python 学习笔记---Python面向对象程序设计(3)

    6 4 2 案例精选 例6 1 自定义数组 在MyArray py文件中 定义了一个数组类 重写了一部分特殊方法以支持数组之间 数组与整数之间的四则运算以及内积 大小比较 成员测试和元素访问等运算符 class MyArray 在内部封装
  • js-用onclick写的手动轮播图

  • C++调用外部应用程序的方法的整理总结

    一 三个SDK函数 WinExec ShellExecute CreateProcess可以实现调用其他程序的要求 其中以WinExec最为简单 ShellExecute比WinExec灵活一些 CreateProcess最为复杂 WinE
  • NestedScrollView使用和理解

    https www jianshu com p fda06c916d6b 一 前言 NestedScrollView 即 支持嵌套滑动的 ScrollView 因此 我们可以简单的把 NestedScrollView 类比为 ScrollV
  • MyBatis动态SQL 多条件查询(if、where、trim标签)

    一 动态SQL概述 以前在使用JDBC操作数据时 如果查询条件特别多 将条件串联成SQL字符串是一件痛苦的事情 通常的解决方法是写很多的if else条件语句对字符串进行拼接 并确保不能忘了空格或在字段的最后省略逗号 MyBatis使用动态
  • Ubuntu18.04 (腾讯云服务器)安装MySQL 5.7,更改MySQL的root密码、并使其可远程登录的一种配置方式

    一 安装MySQL 首先需要在Ubuntu中安装MySQL 5 7相关命令如下 sudo apt get install mysql server 5 7 二 修改MySQL的root密码 1 登录 sudo mysql 上面这一步也可以使
  • 量子通信(QKD)与BB84协议

    量子密钥分发 QKD Quantum key Distribution QKD是量子信息的一个重要分支 也称为 量子保密通信 一个量子通信的课程推荐给大家 论述的全面 详细 https ke qq com course 382160 一个系
  • c#文件下载示例的4种方法

    原文链接 http www jb51 net article 57068 htm C 实现HTTP下载文件的方法
  • 电脑可以聊微信但是无法上网页的解决方法

    电脑可以聊微信但是无法上网页 ping不通百度的IP地址 一般是电脑的DNS出现错误 解决方案如下 打开360安全卫士 点击功能大全中的断网急救箱 进行扫描 之后进行修复 问题即可解决
  • clickhouse重启报错以及远程无法连接

    1 启动报Processing configuration file etc clickhouse server config xml 文件没有写入权限 先添加写入权限 sudo chmod 600 etc clickhouse serve
  • JVM性能优化之Tomcat服务器参数配置优化

    前言 tomcat 服务器在JavaEE项目中使用率非常高 所以在生产环境对tomcat的优化也变得非常重要了 对于tomcat的优化 主要是从2个方面入手 一是tomcat本身的配置 另一个是tomcat所运行的Jvm虚拟机的调优 优化传
  • Windows XP环境下IPSec 隧道的配置

    前言 这是这学期防火墙课程的一个实验 觉得挺有意义 所以记录在博客里 一 实验目的 本实验主要验证IP通信在建立IPSec隧道前后的变化 为了简化实验过程 这里只对ICMP进行加密 但在配置的过程中即可发现 其他IP协议要进行同样的加密也是
  • 【轩说AI】生成模型(1)——自编码器AE+变分自编码器VAE

    文章目录 生成模型 从概率分布的角度去理解 生成 一张图片 生成宝可梦 生成系列图片 自动编码器Auto Encoder AE的模型及其存在的问题 AE中的高斯混合模型 AE的训练情况 举例理解从AE到VAE 变分自动编码器Variatio
  • 经典排序之快速排序

    一 概述 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法 其基本思想为 任取待排序元素序列中的某元素作为基准值 按照该排序码将待排序集合分割成两子序列 左子序列中所有元素均小于基准值 右子序列中所有元素均大于基准值 然后
  • 剑指offer 学习笔记 树中两个节点的最低公共祖先

    面试题68 树中两个节点的最低公共祖先 可以先得到从根节点到这两个节点的路径 之后找出最后一个公共节点 代码中的树为 include