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 ...
随机推荐
- linux实操_shell判断语句
常用判断条件: (1)两个数的比较 = 字符串的比较 -lt 小于 -le 小于等于 -eq 等于 -gt 大于 -ge 大于等于 -ne 不等于 (2)按照文件权限进行判断 -r 有读的权限 -w ...
- js重写页面之后后台如何获取重写后的控件值
需求描述:专业分流系统中,学生在选择志愿时,我想实现在页面按照点击相应专业的顺序来设置选专业的志愿,如首先点击“工商”,则工商专业为第一志愿,接着点击“营销”,则营销专业为第二志愿,以此类推.从而达到 ...
- C语言I 博客作业03
这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 作业要求 我在这个课程的目标是 掌握关系运算.if-else语句.格式化输入语句scanf(),以及常用的数学库函数 这个作业在那个具体方 ...
- Excle导出优化(poi)
搜索词条 1.idea报java.lang.OutOfMemoryError: Java heap space怎么解决? 2.java.lang.OutOfMemoryError: GC overhe ...
- 6-修改虚拟机的SID(sysprep)
一.注意点 1.这种错误一般会出现在克隆的机器里,导致在加入域的时候,报SID一致,加入失败,如下图: 2.使用sysprep修改完之后,需要重启服务器,并且重新配置,重新配网络: 3.如果修改SID ...
- Java8-Lambda-No.03
import java.util.Comparator; import java.util.Objects; import java.util.UUID; import java.util.concu ...
- inline-block默认间距
inline-block元素默认会有间距 解决方法之移除空格 元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自然间距就木有了.考虑到代码可读性,显然连成一行的写法是不可 ...
- php注意事项|要点
1. 用单引号代替双引号来包含字符串,这样做会更快一些.因为 PHP 会在双引号包围的 字符串中搜寻变量,单引号则不会,注意:只有 echo 能这么做,它是一种可以把多个字符 串当作参数的“函数”(译 ...
- leetcode解题报告(11):Search Insert Position
描述 Given a sorted array and a target value, return the index if the target is found. If not, return ...
- ++a和a++不是左值
上面的编译时会出现一下错误: aplus2.c:6:6: error: lvalue required as left operand of assignmentaplus2.c:7:6: error ...