Lowest Common Ancestor of a Binary Tree题解

这是LeetCode上的一道题,让我们先来看一看题目:

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.

简而言之就是已知二叉树,已知二叉树中的两个节点,求这两个节点最近的公共祖先。

同时在代码部分,题目给出了所要求的数据结构,我们可以注意到这一数据结构中,我们只能直接找到这一个节点的左右孩子,但是并不能直接找到他的双亲。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

  

基于这样的数据结构,对于没有学过算法或者学过一些算法不过比较渣的同学(比如我。。。),可能的第一反应就是从根节点开始逐层向下遍历,判断每一个节点是否是所求的公共祖先,然后再找到这些符合条件的节点中最低层的,这种方法显然是十分低效的,因为以每一个节点为根节点的子树都被遍历了很多很多遍。于是为了优化这种算法,我们很自然地想到能否通过调用递归函数来储存中间信息,只对树进行一次遍历解决这个问题。使用这种方法时我们首先需要考虑两个问题:树的遍历方法是先根遍历中根遍历还是什么别的?递归函数的返回值应该储存什么信息?

为了解决这两个问题,我们回归到最近共同祖先这个概念本身。若所求节点是已知节点的最近共同祖先,则说明两点,首先这个节点一定是已知节点的共同祖先,同时这个节点的所有后代(例如左孩子,右孩子)都不是已知节点的共同祖先。因此我们可以总结出该问题的两种不同情况,第一种情况是p,q两个节点分别在所求节点的左子树,右子树中;第二种情况是所求节点本身就是p或q节点。

应对第一种情况,我们发现递归函数的返回值需要能够反映一个节点是否是p或q节点的祖先即可,若一个节点的左右孩子都是p或q节点的祖先,则该节点就是p和q的最近共同祖先。同时我们还需要先对根节点进行特判,判断其是否就是p或q节点,则这时不用再遍历该节点的子树了。经过这些分析,我们决定采取先根遍历的形式,先判断某节点是否是p或q节点,至于递归函数的返回值,如果某节点是p或q的祖先,返回该节点指针,否则返回NULL。

实现这种思路的代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
                if(!root)
			return NULL;      
		if(root == p || root == q)
			return root;
		TreeNode* L = lowestCommonAncestor(root->left, p, q);
		TreeNode* R = lowestCommonAncestor(root->right, p, q);
		if(L && R)
			return root;
		return L ? L : R;
    }
};

  下面我们来分析这个代码的正确性。首先,若p,q两个节点分别在所求节点的左子树,右子树中,则该所求节点是整个二叉树中唯一一个左右节点返回值都不是NULL的节点;若所求节点本身即是p或q节点,则在该节点处会返回该节点的指针,而该遍历该节点的所有祖先节点的返回值都是该节点指针。这确保了这种算法的正确性。

  最后总结一下,这段代码应用了深度搜索的思想和先根遍历的遍历方法,时间复杂度为O(n),形式上也很有美感。感觉Lowest Common Ancestor of a Binary Tree这道题目本身虽然不复杂,但却很能说明一些问题。

时间: 2024-10-21 04:48:31

Lowest Common Ancestor of a Binary Tree题解的相关文章

[LeetCode][JavaScript]Lowest Common Ancestor of a Binary Tree

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 v and w as th

235. Lowest Common Ancestor of a Binary Search Tree && 236. Lowest Common Ancestor of a Binary Tree

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 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

leetcode_236——Lowest Common Ancestor of a Binary Tree(tree,后序遍历)

Lowest Common Ancestor of a Binary Tree Total Accepted: 4228 Total Submissions: 15884My Submissions Question Solution Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wik

235 Lowest Common Ancestor of a Binary Tree

题目 235 Lowest Common Ancestor of a Binary Tree 因为是binary search tree,因此利用没个节点的值进行二分查找即可复杂度O(h) class Solution: # @param {TreeNode} root # @param {TreeNode} p # @param {TreeNode} q # @return {TreeNode} def lowestCommonAncestor(self, root, p, q): if p.

Lowest Common Ancestor of a Binary Tree解析

Lowest Common Ancestor of a Binary Tree Total Accepted: 6162 Total Submissions: 23311 My Submissions Question Solution Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wi

【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) 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 th

88 Lowest Common Ancestor of a Binary Tree

原题网址:https://www.lintcode.com/problem/lowest-common-ancestor-of-a-binary-tree/description 描述 给定一棵二叉树,找到两个节点的最近公共父节点(LCA). 最近公共祖先是两个节点的公共的祖先节点且具有最大深度. 假设给出的两个节点都在树中存在 您在真实的面试中是否遇到过这个题?  是 样例 对于下面这棵二叉树 4 / 3 7 / 5 6 LCA(3, 5) = 4 LCA(5, 6) = 7 LCA(6, 7

LeetCode 236. Lowest Common Ancestor of a Binary Tree; 235. Lowest Common Ancestor of a Binary Search Tree

236. Lowest Common Ancestor of a Binary Tree 递归寻找p或q,如果找到,层层向上返回,知道 root 左边和右边都不为NULL:if (left!=NULL && right!=NULL) return root; 时间复杂度 O(n),空间复杂度 O(H) class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode*

刷题236. Lowest Common Ancestor of a Binary Tree

一.题目说明 题目236. Lowest Common Ancestor of a Binary Tree,在一个二叉树中找两个节点的最近公共祖先.难度是Medium! 二.我的解答 这个用二叉树的递归遍历,稍加改造即可: class Solution{ public: TreeNode* lowestCommonAncestor(TreeNode* root,TreeNode*p,TreeNode*q){ if(root == NULL) return root; if(root == p |