从零学算法235

235.给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

  • 说来惭愧,以前也做到过普通二叉树的,结果只记得了之前写的最笨的层序遍历的方法,这里就不赘述了
  • 他人题解1:还是一样,如果一个结点 root 为 p 和 q 的公共祖先,那么只有三种情况:
    • p q 分别在 root 的左右子树
    • p = root,q 在左右哪里都无所谓了
    • q = root,p 在哪也无所谓了
  • 由于二叉搜索树的特性,接下来事情就变得简单了,如果结点 node 的值小于 root 的值,说明在 root 左侧,大于则在右侧,以此可以判断出 p q 对于 root 来说处于什么位置,那么我们就采用迭代的方式获取最近公共祖先,如果 pq 都在 root 左侧或右侧,就让 root 遍历至 root.left 或 root.right,否则此时 pq 分列 root 两侧,说明 root 此时就是最近公共祖先了,直接退出循环即可
  •   public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
      	// 保证 p < q,这样遍历时条件就不用写成比如 p.val > root.val && q.val > root.val 
      	// 只要 p > root.val 就代表 q > root.val 了,你要保证 p > q 也行,反正同理
          if(p.val > q.val){
              TreeNode tmp = p;
              p = q;
              q = tmp;
          }
          while(root != null){
          	// pq 都在右子树
              if(p.val > root.val)root=root.right;
              // pq 都在左子树
              else if(q.val < root.val)root=root.left;
              else break;
          }
          return root;
      }
    
  • 他人题解2:同理写成递归形式就更加简单了
  •   public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
          if(root.val < p.val && root.val < q.val)
              return lowestCommonAncestor(root.right, p, q);
          if(root.val > p.val && root.val > q.val)
              return lowestCommonAncestor(root.left, p, q);
          return root;
      }
    

你可能感兴趣的:(算法学习,#,树,算法)