## 题目地址 https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/ ## 题目描述 ``` 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] ``` ![236.lowest-common-ancestor-of-a-binary-tree](../assets/problems/236.lowest-common-ancestor-of-a-binary-tree-1.png) ``` 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 nodes 5 and 1 is 3. 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 nodes 5 and 4 is 5, 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。 如果p没有在左子树,那么它一定在右子树(题目限定p一定在树中), 反之亦然。 对于具体的代码而言就是,我们假设这个树就一个结构,然后尝试去解决,然后在适当地方去递归自身即可。 如下图所示: ![236.lowest-common-ancestor-of-a-binary-tree-2](../assets/problems/236.lowest-common-ancestor-of-a-binary-tree-2.png) 我们来看下核心代码: ```js // 如果我们找到了p,直接进行返回,那如果下面就是q呢? 其实这没有影响,但是还是要多考虑一下 if (!root || root === p || root === q) return root; const left = lowestCommonAncestor(root.left, p, q); // 去左边找,我们期望返回找到的节点 const right = lowestCommonAncestor(root.right, p, q);// 去右边找,我们期望返回找到的节点 if (!left) return right; // 左子树找不到,返回右子树 if (!right) return left; // 右子树找不到,返回左子树 return root; // 左右子树分别有一个,则返回root ``` > 如果没有明白的话,请多花时间消化一下 ## 关键点解析 - 用递归的思路去思考树 ## 代码 ```js /* * @lc app=leetcode id=236 lang=javascript * * [236] Lowest Common Ancestor of a Binary Tree * * https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/ * * algorithms * Medium (35.63%) * Total Accepted: 267.3K * Total Submissions: 729.2K * Testcase Example: '[3,5,1,6,2,0,8,null,null,7,4]\n5\n1' * * 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 nodes 5 and 1 is 3. * * * 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 nodes 5 and 4 is 5, 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. * * */ /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {TreeNode} p * @param {TreeNode} q * @return {TreeNode} */ var lowestCommonAncestor = function(root, p, q) { if (!root || root === p || root === q) return root; const left = lowestCommonAncestor(root.left, p, q); const right = lowestCommonAncestor(root.right, p, q); if (!left) return right; // 左子树找不到,返回右子树 if (!right) return left; // 右子树找不到,返回左子树 return root; // 左右子树分别有一个,则返回root }; ``` ## 扩展 如果递归的结束条件改为`if (!root || root.left === p || root.right === q) return root;` 代表的是什么意思,对结果有什么样的影响?