Leetcode之236. Lowest Common Ancestor of a Binary Tree Medium
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]

Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes5and1is3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes5and4is5, since a node can be a descendant of itself according to the LCA definition.
Note:
- All of the nodes' values will be unique.
- p and q are different and both values will exist in the binary tree.
分析:
首先,树的问题,往往涉及递归,之所以涉及递归是因为每一棵树都是由相同结构的多个子树构成。本题可以利用递归的方式,相当于从叶子节点开始,递归地返回如下信息:当前树(或子树)同时包含p和q,则函数返回的结果就是它们的最低公共祖先。如果它们其中之一在子树当中,则结果是它们中的一个。如果它们都不在子树里,则结果返回NULL。
class Solution {
public:
TreeNode * lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// 虽然下面两个if可以写到一起,但所表达的意思是不一样的
if (root == nullptr) {
return nullptr;
}
if (p == root || q == root) {
return root;
}
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if (left == nullptr) { // 如果有一个分支为空,另一个不为空,则返回不为空的节点
return right;
}
else if (right == nullptr) {
return left;
}
else // 如果两个都不为空,则返回二者当前最低祖先节点
return root;
}
};
总结:
书上对这道题的做法麻烦了。首先书上并不是二叉树,而是一颗普通树,所以next存在一个vector里。
其次,书上的做法是先找到p和q两条路径,从根节点出发到p和q分别构成两条链表;
最后,寻找这两条链表的第一个分叉的地方。
注:
如果本题的树是二叉搜索树或者有指向父节点的指针,则思路能更加简单。
1)如果是二叉搜索树,我们只需要从树的根节点开始和两个输入节点进行比较,如果当前节点的值比两个节点的值都大,那么最低的共同父节点一定在当前节点的左子树中,于是下一步遍历当前节点的左子节点;反之,则遍历右子节点。这样,在树中从上到下找到的第一个在两个输入节点的值之间的节点就是最低公共祖先。
2)如果是一棵普通的树,但有指向父节点的指针,此时问题可以换成求两个链表的第一个公共节点。
3)书上面试者提供的从上至下遍历子树的思路相同,其实并不好,因为会涉及到某些结点的多次遍历,一方面我觉得可以利用类似动态规划的方法存储不同节点的遍历结果信息(如用一个字典),下次再用到的时候直接返回结果即可。另一方面,和面试者提出的优化方法一样,利用辅助空间,将从根节点到输入的两个节点的路径分别用两个链表保存,然后将问题转化为两个链表最后公共节点(和注释2类似)。链表的实现用的是C++ list,如:list<TreeNode*> path1。本题是另一种优化思路,自底向上,这样避免了多次遍历相同节点,保证了每个节点只遍历一次。(有一种动态规划的思想)
书上思路如下:
面试者是这么解释这个思路的:所谓两个节点的公共祖先,指的是这两个节点都出现在某个节点的子树中。我们可以从根节点开始遍历一棵树,每遍历到一个节点时,判断两个输入节点是不是在它的子树中。如果在子树中,则分别遍历它的所有子节点,并判断两个输入节点是不是在它们的子树中。这样从上到下一直找到的第一个节点,它自己的子树同时包含两个输入的节点而它的子节点却没有,那么该节点就是最低公共祖先。
Leetcode之236. Lowest Common Ancestor of a Binary Tree Medium的更多相关文章
- 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】236. Lowest Common Ancestor of a Binary Tree
Lowest Common Ancestor of a Binary Tree Given a binary tree, find the lowest common ancestor (LCA) o ...
- 【刷题-LeetCode】236. Lowest Common Ancestor of a Binary Tree
Lowest Common Ancestor of a Binary Tree Given a binary tree, find the lowest common ancestor (LCA) o ...
- LeetCode OJ 236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree 236. Lowest Common Ancestor of a Binary Tree
https://www.cnblogs.com/grandyang/p/4641968.html http://www.cnblogs.com/grandyang/p/4640572.html 利用二 ...
- [LeetCode] 236. Lowest Common Ancestor of a Binary Tree 二叉树的最小共同父节点
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- [LeetCode] 236. Lowest Common Ancestor of a Binary Tree 二叉树的最近公共祖先
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- leetcode@ [236] Lowest Common Ancestor of a Binary Tree(Tree)
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ Given a binary tree, find the ...
- leetcode 236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
随机推荐
- python中pandas库中DataFrame对行和列的操作使用方法
用pandas中的DataFrame时选取行或列: import numpy as np import pandas as pd from pandas import Sereis, DataFram ...
- [React] Create a Query Parameter Modal Route with React Router
Routes are some times better served as a modal. If you have a modal (like a login modal) that needs ...
- python--第六天练习题
#1.正则表达式计算 origin = "1 - 2 * ( ( 60 - 30 + ( -40.0 / 5 ) * ( 9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2 ...
- Jenkins 自动化构建
def pipeId = 1130561944231279390 def pipeLogId def isTagOrBranch def tagOrBranch def imageId def add ...
- SIGAI深度学习第七集 卷积神经网络1
讲授卷积神经网络核心思想.卷积层.池化层.全连接层.网络的训练.反向传播算法.随机梯度下降法.AdaGrad算法.RMSProp算法.AdaDelta算法.Adam算法.迁移学习和fine tune等 ...
- sql server 的 out 和output
sql中out与output --SQLQuery Create By Faywool create proc Proc_OutPutTest--创建 @numA int,--nu ...
- CF540D Bad Luck Island
嘟嘟嘟 看到数据范围很小,就可以暴力\(O(n ^ 3)\)dp啦. 我们令\(dp[i][j][k]\)表示这三种人分别剩\(i, j, k\)个的概率.然后枚举谁挂了就行. 这里的重点在于两个人相 ...
- (转)Git操作
本地修改了许多文件,其中有些是新增的,因为开发需要这些都不要了,想要丢弃掉,可以使用如下命令: git checkout . #本地所有修改的.没有的提交的,都返回到原来的状态 git stash # ...
- windows游戏编程键盘
键盘 首先我们来看一下键盘常用消息 键盘的消息处理过程 键盘消息会有击键消息和字符消息 键盘消息的附加参数 wParam:非系统键的虚拟码 lParam: windows常用虚拟键码及对应的按键
- 【转】java 解析多层json
java分别解析下面两个json字符串 package jansonDemo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjso ...