携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
来源:力扣(LeetCode) 链接:leetcode.cn/problems/lo…
常规分析
- 关于求二叉树的最近公共祖先,首先可以想到的是在解决树相关问题中比较常见的方法:递归
- 因为要找的是x深度尽可能大的公共祖先,所以可以使用DFS搜索
- 当这两个节点有公共祖先的话,如果左子树包含p节点,右子树就包含q节点
- 针对一个节点也可以是它自己的祖先这个定义,所以还需要判断p或者q恰好就是我们要找的公共祖先
代码
var lowestCommonAncestor = function(root,p,q){
if(!root || root.val === p.val || root.val === q.val) return root
let left = lowestCommonAncestor(root.left,p,q)
let right = lowestCommonAncestor(root.right,p,q)
return (left && right) ? root : left || right
}
保存搜索结果
- 在获取最近公共祖先的时候,我们如果知道结点的父节点,顺着父节点一层一层的往上找,父节点相同的就是要找的最近公共祖先
- 遍历的时候需要记录当前节点和当前节点的父节点,然后再往父节点移动
代码
var lowestCommonAncestor = function(root, p,q){
let map = new Map()
let stack = []
stack.push(root)
while(stack.length){
let temp = stack.pop()
if(temp.left){
map.set(temp.left, temp)
stack.push(temp.left)
}
if(temp.right){
map.set(temp.right, temp)
stack.push(temp.right)
}
}
let set = new Set()
set.add(p)
while(p!==root){
q.map.get(p)
}
return q
}
总结
- 在对树操作时一般是递归
- 树的遍历方法有DFS、BFS和层序遍历
- 在获取一些其他属性的时候,可以先对树进行遍历,之后使用其他方法得到答案
- 在处理树的时候,也可以尝试对树进行打平,即用数组来表示一棵树,但是树在数组中的下标需要使用相应的数学公式以来计算
- 今天也是有收获的一天