「这是我参与2022首次更文挑战的第 12 天,活动详情查看:2022首次更文挑战」
题目链接
235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)
题目描述
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
测试用例
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
条件限制
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
题目分析
题目需要我们在一棵二叉树中查找两个节点的公共祖先节点,并且这个祖先节点尽可能的靠近 p, q 节点(即需要我们找到 p, q 第一次交汇的父节点
一个简单的玩法,我们遍历一次二叉树,记录下所有节点的父节点;然后遍历 q 节点的全部父节点,记录到 set 中,再去遍历 q 的父节点,去 set 中尝试匹配(根据题意,p, q 必定会有一个公共的父节点
需要考虑到的特例情况:
① p 可能就是交汇的第一个公共父节点,这个处理简单,我们把 p 也加入到之前定义的 set 中
② q 为交汇的第一个父节点,这种情况下,遍历 q 的父节点一定匹配不到;我们可以为 set 添加 undefined 元素来终止这种情况的遍历查找,然后在返回结果的之后,判断如果匹配结果为 undefined 则返回原始的 q 节点的值
代码实现
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
let dq = q;
let obj = {};
trave(root);
let parents = new Set([p]);
while (obj[p.val] != undefined) {
p = obj[p.val];
parents.add(p)
}
console.log(obj[p.val],p,obj,parents);
while (!parents.has(q)) {
q = obj[q.val];
}
return q;
function trave(root) {
if (root.left != null) {
obj[root.left.val] = root;
trave(root.left);
}
if (root.right != null) {
obj[root.right.val] = root;
trave(root.right);
}
}
};
这次的运行有点出乎意料,仔细排查代码,去掉 console.log,结果就正常多了
优化
仔细阅读题目,发现需要我们处理的是查找二叉树???换句话,我这种解法算是通用的,如果是在查找二叉树上做匹配,性能应该会提升更多,下次再试试