LeetCode算法学习之--Recursion--*二叉树的最近公共祖先*

321 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

大家好今天给大家分享下一道 LeetCode 中等难度 的题目236. 二叉树的最近公共祖先

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

image.png (图片来自leetcode)

分析

1.共同有一个祖先

2.这个祖先的深度最大

3.返回这个节点

解法

1.递归

2.迭代

解法一:递归

思路
1.递归的方式层序遍历访问树的节点,记录结构在treeMap中
2.从q点出 像父节点访问,记录路径在seen中
3.从p点出 像父节点访问,如果访问的父节点中在seen中记录过那么说明这个节点就是pq 的共同祖先
*/
​
var lowestCommonAncestor = function (root, p, q) {
  const treeMap = new Map();
  const seen = new Set();
​
  //   递归的方式层序遍历 从上到下的记录树结构在treeMap中
  function visitTree(root) {
    if (!root) return null;
​
    root.left && treeMap.set(root.left.val, root);
    root.right && treeMap.set(root.right.val, root);
​
    visitTree(root.left);
    visitTree(root.right);
  }
​
  visitTree(root);
​
  function getAncestorNode(treeMap, q, p) {
    //   从q点出 像父节点访问,记录路径在seen中
    while (q) {
      seen.add(q.val);
      q = treeMap.get(q.val);
    }
​
    //   从p点出 像父节点访问,如果访问的父节点中在seen中记录过那么说明这个节点就是pq 的共同祖先
    while (p) {
      if (seen.has(p.val)) {
        return p;
      }
      p = treeMap.get(p.val);
    }
​
    return null;
  }
​
  return getAncestorNode(treeMap, q, p);
};
​
/* 复杂度
时间 O(n)
空间 O(n)
*/

解法二:迭代

思路
1.迭代的做法相似,只是利用了迭代的方式来进行程序遍历记录树结构
*/
var lowestCommonAncestor = function (root, p, q) {
  const treeMap = new Map();
  const seen = new Set();
​
  //   迭代的方式层序遍历 从上到下的记录树结构在treeMap中
  function visitTree(root) {
    if (!root) return null;
    const queue = [];
    queue.push(root);
​
    while (queue.length) {
      const node = queue.shift();
      node.left && treeMap.set(node.left.val, node) && queue.push(node.left);
      node.right && treeMap.set(node.right.val, node) && queue.push(node.right);
    }
  }
​
  visitTree(root);
​
  function getAncestorNode(treeMap, q, p) {
    //   从q点出 像父节点访问,记录路径在seen中
    while (q) {
      seen.add(q.val);
      q = treeMap.get(q.val);
    }
​
    //   从p点出 像父节点访问,如果访问的父节点中在seen中记录过那么说明这个节点就是pq 的共同祖先
    while (p) {
      if (seen.has(p.val)) {
        return p;
      }
      p = treeMap.get(p.val);
    }
​
    return null;
  }
​
  return getAncestorNode(treeMap, q, p);
};
​
/* 复杂度
时间 O(n)
空间 O(n)
*/

总结

今天这道题是主要是练习递归和迭代的方式来记录tree的结构, 和利用Map 来记录tree 的结构

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com

\