【算法与数据结构】236、LeetCode二叉树的最近公共祖先

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

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

二、解法

  思路分析: 根据定义,最近祖先节点需要遍历节点的左右子树,然后才能知道是否为最近祖先节点。那么这种需求是先遍历左右节点,然后遍历中间节点,属于左右中的后序遍历模式。因此在程序当中,我们选择递归中序遍历。输入参数为根节点p q节点。终止条件是当前节点和p q当中任意一个节点相等时就返回,遍历到空节点也返回。因为是后序遍历,根据遍历完左右子树后的返回值确定返回参数,如果返回值都不为空,则当前节点就是最近祖先节点。如果left为空,right不为空,则最近祖先节点在右子树,反之亦然。均为空则返回NULL
  程序如下

class Solution2 {
public:// 后序遍历: 左右中// 1、输入参数TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {// 2、终止条件if (root == q || root == p || root == NULL) return root;    // 如果节点相等或者是空节点返回// 3、单层递归逻辑TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右// 1、返回值if (left != NULL && right != NULL) return root;if (left == NULL && right != NULL) return right;else if (left != NULL && right == NULL) return left;else { //  (left == NULL && right == NULL)return NULL;}}
};

  代码优化

class Solution {
public:// 后序遍历: 左右中// 1、输入参数TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {// 2、终止条件if (root == p || root == q || root == NULL) return root;    // 如果节点相等或者是空节点返回// 3、单层递归逻辑TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右if (left != NULL && right != NULL) return root;if (left == NULL) return right;// 1、返回值return left;}
};

三、完整代码

# include <iostream>
# include <vector>
# include <string>
# include <queue>
using namespace std;// 树节点定义
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode() : val(0), left(nullptr), right(nullptr) {}TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};class Solution {
public:// 后序遍历: 左右中// 1、输入参数TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {// 2、终止条件if (root == p || root == q || root == NULL) return root;    // 如果节点相等或者是空节点返回// 3、单层递归逻辑TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右if (left != NULL && right != NULL) return root;if (left == NULL) return right;// 1、返回值return left;}
};class Solution2 {
public:// 后序遍历: 左右中// 1、输入参数TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {// 2、终止条件if (root == q || root == p || root == NULL) return root;    // 如果节点相等或者是空节点返回// 3、单层递归逻辑TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右// 1、返回值if (left != NULL && right != NULL) return root;if (left == NULL && right != NULL) return right;else if (left != NULL && right == NULL) return left;else { //  (left == NULL && right == NULL)return NULL;}}
};// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {if (!t.size() || t[0] == "NULL") return;    // 退出条件else {node = new TreeNode(stoi(t[0].c_str()));    // 中if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->left);              // 左}if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->right);             // 右}}
}template<typename T>
void my_print(T& v, const string msg)
{cout << msg << endl;for (class T::iterator it = v.begin(); it != v.end(); it++) {cout << *it << ' ';}cout << endl;
}template<class T1, class T2>
void my_print2(T1& v, const string str) {cout << str << endl;for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {cout << *it << ' ';}cout << endl;}
}// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size();  // size必须固定, que.size()是不断变化的vector<int> vec;for (int i = 0; i < size; ++i) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}return result;
}// 前序遍历,找二叉树中指定的键值
TreeNode* traversal_preOrder(TreeNode* cur, int val) {if (cur == NULL) return NULL;if (cur->val == val) return cur;        // 中if (traversal_preOrder(cur->left, val) != NULL) return traversal_preOrder(cur->left, val);        // 左   if (traversal_preOrder(cur->right, val) != NULL) return traversal_preOrder(cur->right, val);     // 右  return NULL;
}int main()
{// 构建二叉树vector<string> t = { "3", "5", "6", "NULL", "NULL", "2", "7", "NULL", "NULL", "4", "NULL", "NULL", "1", "0", "NULL", "NULL", "8", "NULL", "NULL"};   // 前序遍历my_print(t, "目标树");TreeNode* root = new TreeNode();Tree_Generator(t, root);vector<vector<int>> tree = levelOrder(root);my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");// 构建p, q节点int p = 5, q = 1;TreeNode* P_node = traversal_preOrder(root, p);TreeNode* Q_node = traversal_preOrder(root, q);// 找最近公共祖先节点Solution s;TreeNode* result = s.lowestCommonAncestor(root, P_node, Q_node);cout << "节点 " << P_node->val << " 和节点 " << Q_node->val << " 的最近公共祖先节点为 " << result->val << endl;system("pause");return 0;
}

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/130058.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes 部署发布镜像(cubefile:0.4.0)

目录 实验&#xff1a;部署发布镜像&#xff08;cubefile:0.4.0&#xff09; 需求分析&#xff1a; 1、部署Kubenetes环境&#xff1a; 2、撰写 cubefile-deployment.yaml 文件 代码解释&#xff1a; 遇到的问题&#xff1a; 问题解决 &#xff1a; 3、撰写 cubefile-se…

vue2中实现 TDesign 树形懒加载

之前我有写过Element ui的树形懒加载 其主要是通过load函数来实现 而TDesign也是照虎画猫 他也是主要靠load 我们先来看一个基本的组件 <template><t-tree :data"items" :load"load" /> </template><script lang"jsx">…

开启更高效之路,美创科技暗数据发现和数据分类分级系统全新升级

数字经济时代&#xff0c;数据分类分级作为平衡数据保护和流通利用的基础工作&#xff0c;愈发受到广泛的关注。但面对海量繁杂的数据&#xff0c;如何快速地实现数据梳理与分类分级&#xff0c;对于绝大多数组织而言&#xff0c;并非易事—— ◼︎ 在缺少标准方法和自动化、智…

C++之结构体智能指针shared_ptr实例(一百九十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Redis的基本概念与基础用法(1)

在节假日前12306的访问量就会急剧增加&#xff0c;在这种海量用户高并发的情况下就容易出现网站崩溃的情况&#xff0c;造成网站奔溃的罪魁祸首就是关系型数据库&#xff0c;因为关系型数据库有&#xff1a; 性能瓶颈&#xff1a;磁盘IO性能低下扩展瓶颈&#xff1a;数据关系复…

机器学习(10)---特征选择

文章目录 一、概述二、Filter过滤法2.1 过滤法说明2.2 方差过滤2.3 方差过滤对模型影响 三、相关性过滤3.1 卡方过滤3.2 F检验3.3 互信息法3.4 过滤法总结 四、Embedded嵌入法4.1 嵌入法说明4.2 以随机森林为例的嵌入法 五、Wrapper包装法5.1 包装法说明5.2 以随机森林为例的包…

SpringMVC之文件上传下载以及jrebel的使用

目录 前言 文件上传 导入依赖 配置文件上传解析器 配置存放地址 ​编辑 导入PropertiesUtil工具类 编写resource.properties 添加sql 编写PageController类 编写主页展示界面 编写文件上传方法 搭建一个图片上传的操作页面 文件下载 多文件上传 效果展示​编辑 jre…

web UI自动化介绍

文章目录 一、web UI自动化介绍1.1 执行UI自动化测试前提1.2 Selenium介绍以及知识点梳理 二、Selenium 学习2.1 基础2.1.1 环境安装与基础使用2.1.2 web浏览器控制2.1.3 常见控件的八大定位方式2.1.3.1 八大定位方式介绍2.1.3.2 NAME、ID定位2.1.3.3 css_selector定位2.1.3.4 …

c++qt day2

封装一个结构体&#xff0c;结构体中包含一个私有数组&#xff0c;用来存放学生的成绩&#xff0c;包含一个私有变量&#xff0c;用来记录学生个数&#xff0c; 提供一个公有成员函数&#xff0c;void setNum(int num)用于设置学生个数 提供一个公有成员函数&#xff1a;void…

Cascade-MVSNet CVPR-2020 学习笔记总结 译文 深度学习三维重建

文章目录 4 Cascade-MVSNet CVPR-20204.0 主要特点4.1 背景介绍4.2 代价体构造回顾4.3 Cascade-MVSNet4.4 Loss的设置4.5 Cascade-MVSNet实战操作4.6 总结4 Cascade-MVSNet CVPR-2020 深度学习三维重建 cascade-MVSNet-CVPR-202(源码、原文、译文 )下载 4.0 主要特点 采用特…

Python用GAN生成对抗性神经网络判别模型拟合多维数组、分类识别手写数字图像可视化...

全文链接&#xff1a;https://tecdat.cn/?p33566 生成对抗网络&#xff08;GAN&#xff09;是一种神经网络&#xff0c;可以生成类似于人类产生的材料&#xff0c;如图像、音乐、语音或文本&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 最近我们…

Python之数据库(MYSQL)连接

一&#xff09;数据库SQL语言基础 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database…

C高级day4循环语句

1&#xff0c;思维导图 运行结果为&#xff1a; 运行结果为&#xff1a;

【hive】—原有分区表新增加列(alter table xxx add columns (xxx string) cascade;)

项目场景&#xff1a; 需求&#xff1a;需要在之前上线的分区报表中新增加一列。 实现方案&#xff1a; 1、创建分区测试表并插入测试数据 drop table test_1; create table test_1 (id string, score int, name string ) partitioned by (class string) row format delimit…

工作游戏时mfc140u.dll丢失的解决方法,哪个方法可快速修复mfc140u.dll问题

在 Windows 操作系统中&#xff0c;mfc140u.dll 文件是非常重要的一个组件&#xff0c;许多基于 MFC&#xff08;Microsoft Foundation Classes&#xff09;的程序都需要依赖这个文件。然而&#xff0c;有些用户在运行这些程序时可能会遇到mfc140u.dll丢失的问题&#xff0c;导…

12个微服务架构模式最佳实践

微服务架构是一种软件开发技术&#xff0c;它将大型应用程序分解为更小的、可管理的、独立的服务。每个服务负责特定的功能&#xff0c;并通过明确定义的 API 与其他服务进行通信。微服务架构有助于实现软件系统更好的可扩展性、可维护性和灵活性。 接下来&#xff0c;我们将介…

机器学习(9)---线性回归中的公式推导(手推)、闭式解和数值解

文章目录 一、闭式解&#xff08;解析解&#xff09;二、数值解三、一元线性回归中w和b的推导四、多元线性回归中w的推导 一、闭式解&#xff08;解析解&#xff09; 1. 在机器学习中&#xff0c;闭式解也被称为解析解&#xff08;analytical solution&#xff09;&#xff0c;…

【LeetCode-面试经典150题-day23】

目录 108. 将有序数组转换为二叉搜索树 148.排序链表 427.建立四叉树 23.合并K个升序链表 108. 将有序数组转换为二叉搜索树 题意&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二…

R语言统计学DOE实验设计:用平衡不完全区组设计(BIBD)分析纸飞机飞行时间实验数据...

全文链接&#xff1a;http://tecdat.cn/?p31010 平衡不完全区组设计&#xff08;BIBD&#xff09;是一个很好的研究实验设计&#xff0c;可以从统计的角度看各种所需的特征&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 最近我们被客户要求撰写关于BIBD的研…

【C++进阶】二叉树进阶之二叉搜索树

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…