leetcode面试准备:Lowest Common Ancestor of a Binary Search Tree & Binary Tree

1 题目

Binary Search Tree的LCA

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5

For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

接口: TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)

Binary Tree的LCA

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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

接口: TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)

2 思路

在二叉树数中寻找两个节点的最低公共父节点。更容易一点的题目是限定在搜索二叉树中。

搜索二叉树:左子树 < root < 右子树,即中序遍历有序。

思路1

遍历2次,找到节点pq的路径,然后在遍历1次两条路径,找到公共的最低节点。这个节点是所求的。

  • 搜索二叉树:利用BST性质,判断节点值的大小,很容易找到节点的路径。
  • 一般二叉树:DFS找公共节点

复杂度: 遍历3次,用了额外的储存空间。如何分析树的时间和空间复杂度?

思路2

树的结构,很容易想到递归。LCA要么在root上,要么在左右子树中。

  • 搜索二叉树

    根据BST的性质,两个节点p,q的公共袓先root, 一定满足p <= root <= q 或者 p >= root >= q。

    使用递归可以轻松解决此问题。分为三种情况讨论:
  1. P, Q都比root小,则LCA在左树,我们继续在左树中寻找LCA
  2. P, Q都比root大,则LCA在右树,我们继续在右树中寻找LCA
  3. 其它情况,表示P,Q在root两边,或者二者其一是root,或者都是root,这些情况表示root就是LCA,直接返回root即可。
  • 一般二叉树

    The idea is to traverse the tree starting from root. 具体见代码实现吧。
  1. If any of the given keys (n1 and n2) matches with root, then root is LCA (assuming that both keys are present).
  2. If root doesn’t match with any of the keys, we recur for left and right subtree. The node which has one key present in its left subtree and the other key present in right subtree is the LCA.
  3. If both keys lie in left subtree, then left subtree has LCA also, otherwise LCA lies in right subtree.

3 代码

BST的LCA

只写了思路2的代码

	// 递归
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return root;
final int value = root.val;
if (Math.max(p.val, q.val) < value)
return lowestCommonAncestor(root.left, p, q);
if (Math.min(p.val, q.val) > value)
return lowestCommonAncestor(root.right, p, q);
return root;
} // 迭代做法
public TreeNode lca(TreeNode root, TreeNode p, TreeNode q) {
TreeNode cur = root;
for (;;) {
int value = cur.val;
if (p.val < value && q.val < value)
cur = cur.left;
else if (p.val > value && q.val > value)
cur = cur.right;
else
return cur;
}
}

BT的LCA

思路2的代码

	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
} // If the root is one of a or b, then it is the LCA
if (root == p || root == q) {
return root;
} TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q); // If both nodes lie in left or right then their LCA is in left or right,
// Otherwise root is their LCA
if (left != null && right != null) {
return root;
} return (left != null) ? left : right;
}

思路1的代码

	public TreeNode lca(TreeNode root, TreeNode p, TreeNode q) {
Deque<TreeNode> pPath = new LinkedList<TreeNode>();
Deque<TreeNode> qPath = new LinkedList<TreeNode>();
findPath(root, p, pPath);
findPath(root, q, qPath); TreeNode prev = null;
for (; !pPath.isEmpty() && !qPath.isEmpty();) {
TreeNode parent = pPath.removeFirst();
if (parent == qPath.removeFirst()) {
prev = parent;
} else {
break;
}
}
return prev;
} /**
* DFS 寻找路径
*/
private boolean findPath(TreeNode root, TreeNode node, Deque<TreeNode> path) {
if (root == null)
return false;
if (root == node) {
path.addLast(root);
return true;
}
path.addLast(root);
if (findPath(root.left, node, path))
return true;
if (findPath(root.right, node, path))
return true;
path.removeLast();
return false;
}

4 总结

树的题目,不熟悉,多总结一下吧。

5 参考

leetcode面试准备:Lowest Common Ancestor of a Binary Search Tree & Binary Tree的更多相关文章

  1. 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  2. Leetcode之236. Lowest Common Ancestor of a Binary Tree Medium

    236. Lowest Common Ancestor of a Binary Tree Medium https://leetcode.com/problems/lowest-common-ance ...

  3. 【一天一道LeetCode】#235. Lowest Common Ancestor of a Binary Search Tree

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  4. 【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 [LeetCode] https://leet ...

  5. LeetCode 【235. Lowest Common Ancestor of a Binary Search Tree】

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  6. 【LeetCode 236】Lowest Common Ancestor of a Binary Tree

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  7. 【LeetCode 235】Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  8. LeetCode OJ 236. Lowest Common Ancestor of a Binary Tree

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  9. LeetCode OJ 235. Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

随机推荐

  1. 如何理解 Redux?

    作者:Wang Namelos 链接:https://www.zhihu.com/question/41312576/answer/90782136 来源:知乎 著作权归作者所有,转载请联系作者获得授 ...

  2. 数据库连接池php-cp介绍

    php-cp(php-connect-pool)是用php扩展写的一个数据库连接池. 我们知道php开发速度快,适合创业快速迭代,但当流量大了之后,php大量的短连接给db层造成多余的消耗,而php处 ...

  3. WPF窗体视图中绑定Resources文件中字符串时,抛出:System.Windows.Markup.StaticExtension

    问题描述: 在Resources.resx定义了一个静态字符串字段Title,并在WPF窗体视图中绑定为窗体的标题: Title="{x:Static local:Resources.Tit ...

  4. 安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常)

    安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常) 刚安装完后用plSql登录正常. 在dos命令行下 输入  sqlplus 用户 ...

  5. ubuntu netbeans compile ygopro client with google protobuf lib

    environment: ubuntu 16.04 netbeans 8.2 ygopro Fluorohydride with Irrlicht Game Engine 问题1: google pr ...

  6. Codevs 1171 潜伏者 2009年NOIP全国联赛提高组

    1171 潜伏者 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description [问题描述] R 国和S 国正陷 ...

  7. 最近使用Qt遇到的一些小问题解决办法总结

    1. 我想获取当前星期几这样的,我没在API里面找到这样的函数,但是我找到了今天是第几天这样的,所以自己转换一下就OK了: typedef struct { int numInWeek; QStrin ...

  8. 检查mysql数据库是否存在坏表脚本

    #!/bin/bash #此脚本的主要用途是检测mysql服务器上所有的db或者单独db中的坏表 #变量说明 pass mysql账户口令 name mysql账号名称 data_path mysql ...

  9. Winform动态加载TabControl用法

    private void BindTabData() { dtIPD = new DataTable(); //drItem = new DataTable(); //获取[项目大类]列表显示于 Ta ...

  10. properties文件的继承(套用)关系

    现项目中有多个配置文件分布于/props____def.properties____/env_______def.propertiess_______/dev_______def.properties ...