1 问题

求二叉树中俩个节点的最低共同父节点,比如二叉树如下

                42         61     3   5     7 

比如节点1和3两个节点的最低共同父节点是2,节点3和5两个节点的最低共同父节点是4,节点5和6两个节点的最低共同父节点是6,

也有可能其中1个节点或者2个节点不在二叉树里面,那么他们就没有最低共同父节点。

2 分析

                42         61     3   5     7 

比如我们求节点1和3两个节点的最低共同父节点,我们保存每个根节点到该节点的最短路径节点值,比如节点1的路径就是4->2->1 然后节点3的路径是4->2->3,然后我们再把这个保存的2个路径依次从尾巴进行进行比较,然后就能获取两个节点的最低共同父节点值。

3 代码实现

#include <iostream>
#include <vector>
#include <stdlib.h>using namespace std;typedef struct Tree
{int value;struct Tree* left;struct Tree* right;Tree(int value) : value(value), left(NULL), right(NULL) {}
} Tree;class CommonParentNode
{
public:bool hasPath(Tree* head, Tree* node, std::vector<Tree *>& vector){if (head == NULL)return false;///先把我们的遍历节点保存到vector里面去vector.push_back(head);if (head == node)return true;//如果这样写只能说明子递归return值了,但是这个函数没有返回值。if (head->left != NULL && hasPath(head->left, node, vector))return true;if (head->right != NULL && hasPath(head->right, node, vector))return true;//这里一定要调用pop_back函数,如果这个节点的左右子节点都为空或者左子树或者右子树里面不包含这个我们的节点,//这个节点就要弹出来,如果没有这个函数,那么我们的vector里面保存的先序遍历到这个节点的所有节点值,//而不是根节点到这个节点的最短距离。vector.pop_back();return false;}Tree* getCommmonParent(Tree* node, Tree* node1, Tree* node2){if (node == NULL || node1 == NULL || node2 == NULL){std::cout << "node == NULL || node1 == NULL || node2 == NULL" << std::endl;return NULL;}vector<Tree *> vector1;vector<Tree *> vector2;bool result1 = hasPath(node, node1, vector1);if (!result1)return NULL;bool result2 = hasPath(node, node2, vector2);if (!result2)return NULL;//我们vector依次保存的是从头结点到该节点的路径,我们遍历的时候应该从vector的尾巴开始遍历,注释的遍历错了,要注意// for (int i = 0; i < vector1.size(); ++i)// {//     for (int j = 0; j < vector2.size(); ++j)//     {//         //if (vector1[i]->value == vector2[j]->value)//         if (vector1[i] == vector2[j])//         {//             std::cout << "common parent node value is" << vector1[i]->value << std::endl;//             return vector1[i];//         }//     }// } for (int i = vector1.size() - 1; i >= 0; --i){for (int j = vector2.size() - 1; j >= 0; --j){//if (vector1[i]->value == vector2[j]->value)if (vector1[i] == vector2[j]){return vector1[i];}}} return NULL; }
};int main() {Tree *node1 , *node2 , *node3, *node4, *node5, *node6, *node7, *node8;node1 = (Tree *)malloc(sizeof(Tree));node2 = (Tree *)malloc(sizeof(Tree));node3 = (Tree *)malloc(sizeof(Tree));node4 = (Tree *)malloc(sizeof(Tree));node5 = (Tree *)malloc(sizeof(Tree));node6 = (Tree *)malloc(sizeof(Tree));node7 = (Tree *)malloc(sizeof(Tree)); node8 = (Tree *)malloc(sizeof(Tree)); node1->value = 4;node2->value = 2;node3->value = 6;node4->value = 1;node5->value = 3;node6->value = 5;node7->value = 7;node8->value = 8;node1->left = node2;node1->right = node3;node2->left = node4;node2->right = node5;node3->left = node6;node3->right = node7;node4->left = NULL;node4->right = NULL;node5->left = NULL;node5->right = NULL;node6->left = NULL;node6->right = NULL;node7->left = NULL;node7->right = NULL;/*** 42         61     3   5      7     **/CommonParentNode commonParentNode;Tree *commonTreeNode = NULL;commonTreeNode = commonParentNode.getCommmonParent(node1, node5, node7);if (!commonTreeNode){std::cout << "the two node do not find commonTreeNode" << std::endl;return -1;}std::cout << "commonTreeNode parent node value is " << commonTreeNode->value << std::endl;return 0;
}

4 运行结果

commonTreeNode parent node value is 4

5 总结

这个题目的思路是保存根节点到每个节点中途最短路径父节点值,然后进行比较,同时我们应该可以知道求根节点到该节点最短路径的每个节点值,就是vector里面保存的每个节点,同时也知道根节点到该节点的高度值,也就是这个vecter里面保存数据的大小,既vector.size()函数的值,代码和上面部分代码一样。

bool hasPath(Tree* head, Tree* node, std::vector<Tree *>& vector){if (head == NULL)return false;///先把我们的遍历节点保存到vector里面去vector.push_back(head);if (head == node)return true;//如果这样写只能说明子递归return值了,但是这个函数没有返回值。if (head->left != NULL && hasPath(head->left, node, vector))return true;if (head->right != NULL && hasPath(head->right, node, vector))return true;//这里一定要调用pop_back函数,如果这个节点的左右子节点都为空或者左子树或者右子树里面不包含这个我们的节点,//这个节点就要弹出来,如果没有这个函数,那么我们的vector里面保存的先序遍历到这个节点的所有节点值,//而不是根节点到这个节点的最短距离。vector.pop_back();return false;}

很经典的代码。

剑指offer之求二叉树中两个节点的最低共同父节点相关推荐

  1. 《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值

    一.序列化二叉树: 1.题目: 请实现两个函数,分别用来序列化和反序列化二叉树. 2.解题思路: (1)根据前序遍历规则完成序列化与反序列化.所谓序列化指的是遍历二叉树为字符串:所谓反序列化指的是依据 ...

  2. 《剑指offer》求二叉树的最小深度(非递归法)

    题目:求二叉树的最小深度(实际上该题来自leetcode) 解析:递归法简单些,下面演示下非递归.无外乎层次遍历二叉树了,思想是用current记录当前层的节点数,next记录下一层的节点数,用队列保 ...

  3. 剑指Offer面试题:31.两个链表的第一个公共节点

    一.题目:两个链表的第一个公共节点 题目:输入两个链表,找出它们的第一个公共结点. 链表结点定义如下,这里使用C#语言描述: public class Node{public int key;publ ...

  4. 剑指offer之求两个数之和(不能使用四则运算)

    1 题目 剑指offer之求两个数之和(不能使用四则运算) 2 代码实现 #include<stdio.h>int add(int num1, int num2) {int sum1;in ...

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

    [LeetCode]剑指 Offer 68 - II. 二叉树的最近公共祖先 文章目录 [LeetCode]剑指 Offer 68 - II. 二叉树的最近公共祖先 一.DFS 一.DFS 祖先的定义 ...

  6. 剑指 Offer II 014. 字符串中的变位词

    剑指 Offer II 014. 字符串中的变位词 题目 示例 解答 题目来源为leetcode 题目 给定两个字符串s1和s2,写一个函数来判断s2是否包含s1的某个变位词. 换句话说,第一个字符串 ...

  7. LeetCode 剑指Offer 64.求1,2到n的和, 不使用循环/判断及乘除

    题目 剑指 Offer 64. 求1+2+-+n 求 1+2+-+n ,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 示例 1: ...

  8. 【LeetCode】剑指 Offer 07. 重建二叉树

    [LeetCode]剑指 Offer 07. 重建二叉树 文章目录 [LeetCode]剑指 Offer 07. 重建二叉树 package offer;import java.util.ArrayD ...

  9. 【LeetCode】剑指 Offer 55 - I. 二叉树的深度

    [LeetCode]剑指 Offer 55 - I. 二叉树的深度 文章目录 [LeetCode]剑指 Offer 55 - I. 二叉树的深度 一.后序遍历(DFS) 二.层序遍历 一.后序遍历(D ...

最新文章

  1. DevExpress最强干货|实用示例、更新等你来体验!
  2. 香港浸会大学计算机系助理教授招人工智能方向2022年PhD
  3. 在win8上安装mysql_如何在Win8系统上安装MySQL 5.6
  4. C# WinfForm 控件之dev报表 XtraReport (六) 图表Charts 无内容
  5. 【Keras】学习笔记(二)
  6. 开启php的ssl,php怎么开启ssl?开启ssl的方法
  7. java面试题-精心准备
  8. 将Java应用程序作为Windows服务安装
  9. Linux中变量#,@,0,1,2,*,$$,$?的含义
  10. java 1000以内的完数
  11. JavaScriptjQuery.动态删除元素
  12. portlet_Portlet生命周期
  13. Linux配置Anaconda3环境变量的问题
  14. java.io.File 的一些记录
  15. 简单说说jsonp原理
  16. python编程语言可以做游戏吗_用Python编程可以制作掷骰子游戏吗
  17. 基于STM32的0.96寸OLED显示屏显示数据
  18. 生命以负熵为生:Web3行业2022年之怪现象
  19. win10 便签显示设置
  20. DTP,VTP,链路聚合

热门文章

  1. Prism区域异常问题分析(导航失效?)
  2. C sharp实例:华盾武器门数据接收和解析
  3. 使用c#接入华为云-内容审核
  4. NET问答: 如何给 ASP.NET Core 配置指定端口 ?
  5. C#中HashTable、Dictionary、ConcurrentDictionary区别
  6. Monitor 监测CPU与内存
  7. 【日常排雷】 .Net core 生产环境appsetting读取失败
  8. .NET Core 使用Topshelf方式创建Windows服务
  9. 你知道这个C#开发跨平台APP的样例介绍开源项目吗?
  10. .NET 5.0正式发布,有什么功能特性(翻译)