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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

分析:

给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。

最近公共祖先是两个节点的公共的祖先节点且具有最大深度。

这道题可以用分治法完成,

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。

求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。

当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。

对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。

如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。

运用分治策略解决的问题一般来说具有以下特点:
 
1、原问题可以分解为多个子问题
 
这些子问题与原问题相比,只是问题的规模有所降低,其结构和求解方法与原问题相同或相似。
 
2、原问题在分解过程中,递归地求解子问题
 
由于递归都必须有一个终止条件,因此,当分解后的子问题规模足够小时,应能够直接求解。
 
3、在求解并得到各个子问题的解后
 
应能够采用某种方式、方法合并或构造出原问题的解。
 
这道题可以使用深度优先搜索的思路,从叶子节点开始向上查找,在这个过程中标记子树中出现的目标节点。
实际要看的是递归函数和实际处理部分的相对位置,
实际处理在上,那就是从上向下,因为先处理再递归,
实际处理在下,那就是从下向上,因为先递归再处理,处理是等到递归返回之后做的。
 
如果某侧子树中有目标节点,标记为那个目标节点,如果没有,标记为null。
如果左子树、右子树都有标记,说明p、q位于根节点的两侧,最小公共祖先就是root了。
 
查看左子树中是否有目标节点,没有则为null,
查看右子树中是否有目标节点,没有则为null,
如果left、 right都不为空,说明左右子树都有目标节点,目标节点就是root。
如果某一侧有目标节点,则标记为目标节点。

////////

如果一个节点左子树有两个目标节点中的一个,右子树没有,那这个节点肯定不是最小公共祖先。
如果一个节点右子树有两个目标节点中的一个,左子树没有,那这个节点肯定也不是最小公共祖先。
只有一个节点正好左子树有,右子树也有的时候,才是最小公共祖先。

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 在root为根的二叉树中找A,B的LCA:
// 如果找到了就返回这个LCA
// 如果只碰到A,就返回A
// 如果只碰到B,就返回B
// 如果都没有,就返回null
if (root == null) {
return null;
}
if (root == p || root == q) {
return root;
}
// Divide
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q); // Conquer
if(left != null && right != null) {
return root;
}
if (left != null) {
return left;
}
if (right != null) {
return right;
}
return null;
}
}

根空返空,

根等p或根等q,返根

左子树递归,

右子树递归,

左非空且右非空返根,

左非空返左,

右非空返右,

返空。

leetcode 236. Lowest Common Ancestor of a Binary Tree的更多相关文章

  1. [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 ...

  2. [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 ...

  3. 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 ...

  4. (medium)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 ...

  5. [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. Accordi ...

  6. [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 ...

  7. LeetCode 236 Lowest Common Ancestor of a Binary Tree 二叉树两个子节点的最低公共父节点

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  8. Java for LeetCode 236 Lowest Common Ancestor of a Binary Tree

    解题思路一: DFS到每个节点的路径,根据路径算出LCA: public class Solution { public TreeNode lowestCommonAncestor(TreeNode ...

  9. [leetcode]236. Lowest Common Ancestor of a Binary Tree树的最小公共祖先

    如果一个节点的左右子树上分别有两个节点,那么这棵树是祖先,但是不一定是最小的,但是从下边开始判断,找到后一直返回到上边就是最小的. 如果一个节点的左右子树上只有一个子树上遍历到了节点,那么那个子树可能 ...

随机推荐

  1. C#中使用代码动态改变配置文件信息

    static void Main(string[] args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("../../App.co ...

  2. setInterval js

    $('#start_scan').on('click',function(){ if(timer == undefined){ timer = setInterval(scan,1000) start ...

  3. ORACLE函数大全

    SQL中的单记录函数 1.ASCII 返回与指定的字符对应的十进制数; SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ...

  4. Android计算器开发实例

    Android简单计算器开发实例如图: ==================================================== activity_main.xml 代码如下: < ...

  5. listen()

    创建一个套接口并监听申请的连接. #include <winsock.h> int PASCAL FAR listen( SOCKET s, int backlog); S:用于标识一个已 ...

  6. Java导包——import语句

    使用语句import org.common.demo01.Demo: 或者import org.common.demo01.*: 如果一个类声明为public class,则文件名称必须与类名称一致, ...

  7. CentOS安装oracle12C

    安装虚拟系统CentOS6.5,分配给至少1G的内存,其他条件适当高些,具体参考官方文档 一.安装数据库: 1.安装依赖软件包 yum install binutils -y yum install ...

  8. (HBase) Error: JAVA_HOME is not set and Java could not be found

    请查看Linux系统环境变量 JAVA_HOME 是否设置.. 两种方法 env //查看全部系统变量 或者 echo $JAVA_HOME //查看JAVA_HOME变量值 如果没有设置则输出空 没 ...

  9. GOF业务场景的设计模式-----单例模式

    个人觉得 纯粹的学习设计模式,是不对的.也不能为了使用设计模式,而硬搬设计模式来使用 单例模式可能是 最简单的设计模式也是 大家知道最多的设计模式.当然 ,有很多种写法 定义:确保一个类只有一个实例, ...

  10. 黑客攻防技术宝典Web实战篇(三)web攻击方式总结

    web攻击的手段无非就是使服务器资源耗尽,使服务器无法接收正常请求. 一.DDos攻击 二.DRDos攻击 三.慢攻击 与Ddos攻击相反,慢攻击并不是以多取胜,而是靠保持连接.