鉴于两个值的数值N1,并在二叉搜索树N2,发现将L把所欠的Çommon一个ncestor(LCA)。您可以假设这两个值都存在于树中。
例子:
树: 输入: 10和14的LCA输出: 12说明: 12是最接近10和14的节点,这是两个节点的祖先。输入: 8和14的LCA输出: 8说明: 8是最接近8和14的节点,这是两个节点的祖先。输入: 10和22的LCA输出: 20说明: 20是最接近10和22的节点,这是两个节点的祖先。
以下是维基百科中LCA的定义:
Let T be a rooted tree. The lowest common ancestor between two nodes n1 and n2 is defined as the lowest node in T that has both n1 and n2 as descendants (where we allow a node to be a descendant of itself).
The LCA of n1 and n2 in T is the shared ancestor of n1 and n2 that is located farthest from the root. Computation of lowest common ancestors may be useful, for instance, as part of a procedure for determining the distance between pairs of nodes in a tree: the distance from n1 to n2 can be computed as the distance from the root to n1, plus the distance from the root to n2, minus twice the distance from the root to their lowest common ancestor. (Source Wiki)
方法:对于二叉搜索树,从上到下遍历树时,位于两个数字n1和n2之间的第一个节点是节点的LCA,即深度最小的第一个节点n位于n1和n2之间。 n2(n1 <= n <= n2)n1 算法: 执行: 输出: 复杂度分析: 迭代实现:上面的解决方案使用递归。递归解决方案需要以函数调用堆栈的形式提供额外的空间。因此,可以实现一种迭代解决方案,该解决方案不会以函数调用堆栈的形式占用空间。 执行: 复杂度分析: 您可能还希望看到以下文章: 二叉树中的最低共同祖先 使用父指针的LCA 使用RMQ在二叉树中查找LCA 锻炼
C
// A recursive C program to find LCA of two nodes n1 and n2.
#include
C++
// A recursive CPP program to find
// LCA of two nodes n1 and n2.
#include
Java
// Recursive Java program to print lca of two nodes
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
/* Function to find LCA of n1 and n2. The function assumes that both
n1 and n2 are present in BST */
Node lca(Node node, int n1, int n2)
{
if (node == null)
return null;
// If both n1 and n2 are smaller than root, then LCA lies in left
if (node.data > n1 && node.data > n2)
return lca(node.left, n1, n2);
// If both n1 and n2 are greater than root, then LCA lies in right
if (node.data < n1 && node.data < n2)
return lca(node.right, n1, n2);
return node;
}
/* Driver program to test lca() */
public static void main(String args[])
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
}
}
// This code has been contributed by Mayank Jaiswal
Python
# A recursive python program to find LCA of two nodes
# n1 and n2
# A Binary tree node
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to find LCA of n1 and n2. The function assumes
# that both n1 and n2 are present in BST
def lca(root, n1, n2):
# Base Case
if root is None:
return None
# If both n1 and n2 are smaller than root, then LCA
# lies in left
if(root.data > n1 and root.data > n2):
return lca(root.left, n1, n2)
# If both n1 and n2 are greater than root, then LCA
# lies in right
if(root.data < n1 and root.data < n2):
return lca(root.right, n1, n2)
return root
# Driver program to test above function
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
C#
using System;
// Recursive C# program to print lca of two nodes
// A binary tree node
public class Node
{
public int data;
public Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
public class BinaryTree
{
public Node root;
/* Function to find LCA of n1 and n2. The function assumes that both
n1 and n2 are present in BST */
public virtual Node lca(Node node, int n1, int n2)
{
if (node == null)
{
return null;
}
// If both n1 and n2 are smaller than root, then LCA lies in left
if (node.data > n1 && node.data > n2)
{
return lca(node.left, n1, n2);
}
// If both n1 and n2 are greater than root, then LCA lies in right
if (node.data < n1 && node.data < n2)
{
return lca(node.right, n1, n2);
}
return node;
}
/* Driver program to test lca() */
public static void Main(string[] args)
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
}
}
// This code is contributed by Shrikant13
C
// A recursive C program to find LCA of two nodes n1 and n2.
#include
C++
// A recursive CPP program to find
// LCA of two nodes n1 and n2.
#include
Java
// Recursive Java program to print lca of two nodes
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
/* Function to find LCA of n1 and n2.
The function assumes that both
n1 and n2 are present in BST */
static Node lca(Node root, int n1, int n2)
{
while (root != null)
{
// If both n1 and n2 are smaller
// than root, then LCA lies in left
if (root.data > n1 &&
root.data > n2)
root = root.left;
// If both n1 and n2 are greater
// than root, then LCA lies in right
else if (root.data < n1 &&
root.data < n2)
root = root.right;
else break;
}
return root;
}
/* Driver program to test lca() */
public static void main(String args[])
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
}
}
// This code is contributed by SHUBHAMSINGH10
Python
# A recursive python program to find LCA of two nodes
# n1 and n2
# A Binary tree node
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to find LCA of n1 and n2.
# The function assumes that both
# n1 and n2 are present in BST
def lca(root, n1, n2):
while root:
# If both n1 and n2 are smaller than root,
# then LCA lies in left
if root.data > n1 and root.data > n2:
root = root.left
# If both n1 and n2 are greater than root,
# then LCA lies in right
elif root.data < n1 and root.data < n2:
root = root.right
else:
break
return root
# Driver program to test above function
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
# This Code is Contributed by Sumit Bhardwaj (Timus)
C#
using System;
// Recursive C# program to print lca of two nodes
// A binary tree node
public class Node
{
public int data;
public Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
public class BinaryTree
{
public Node root;
/* Function to find LCA of n1 and n2.
The function assumes that both
n1 and n2 are present in BST */
public virtual Node lca(Node root, int n1, int n2)
{
while (root != null)
{
// If both n1 and n2 are smaller than
// root, then LCA lies in left
if (root.data > n1 && root.data > n2)
root = root.left;
// If both n1 and n2 are greater than
// root, then LCA lies in right
else if (root.data < n1 && root.data < n2)
root = root.right;
else break;
}
return root;
}
/* Driver program to test lca() */
public static void Main(string[] args)
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
}
}
// This code is contributed by Shrikant13
LCA of 10 and 14 is 12
LCA of 14 and 8 is 8
LCA of 10 and 22 is 20
上述解决方案的时间复杂度为O(h),其中h是树的高度。
如果忽略递归堆栈空间,则上述解决方案的空间复杂度是恒定的。 C
// A recursive C program to find LCA of two nodes n1 and n2.
#include
C++
// A recursive CPP program to find
// LCA of two nodes n1 and n2.
#include
Java
// Recursive Java program to print lca of two nodes
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
/* Function to find LCA of n1 and n2.
The function assumes that both
n1 and n2 are present in BST */
static Node lca(Node root, int n1, int n2)
{
while (root != null)
{
// If both n1 and n2 are smaller
// than root, then LCA lies in left
if (root.data > n1 &&
root.data > n2)
root = root.left;
// If both n1 and n2 are greater
// than root, then LCA lies in right
else if (root.data < n1 &&
root.data < n2)
root = root.right;
else break;
}
return root;
}
/* Driver program to test lca() */
public static void main(String args[])
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
}
}
// This code is contributed by SHUBHAMSINGH10
Python
# A recursive python program to find LCA of two nodes
# n1 and n2
# A Binary tree node
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to find LCA of n1 and n2.
# The function assumes that both
# n1 and n2 are present in BST
def lca(root, n1, n2):
while root:
# If both n1 and n2 are smaller than root,
# then LCA lies in left
if root.data > n1 and root.data > n2:
root = root.left
# If both n1 and n2 are greater than root,
# then LCA lies in right
elif root.data < n1 and root.data < n2:
root = root.right
else:
break
return root
# Driver program to test above function
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
# This Code is Contributed by Sumit Bhardwaj (Timus)
C#
using System;
// Recursive C# program to print lca of two nodes
// A binary tree node
public class Node
{
public int data;
public Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
public class BinaryTree
{
public Node root;
/* Function to find LCA of n1 and n2.
The function assumes that both
n1 and n2 are present in BST */
public virtual Node lca(Node root, int n1, int n2)
{
while (root != null)
{
// If both n1 and n2 are smaller than
// root, then LCA lies in left
if (root.data > n1 && root.data > n2)
root = root.left;
// If both n1 and n2 are greater than
// root, then LCA lies in right
else if (root.data < n1 && root.data < n2)
root = root.right;
else break;
}
return root;
}
/* Driver program to test lca() */
public static void Main(string[] args)
{
// Let us construct the BST shown in the above figure
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
int n1 = 10, n2 = 14;
Node t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
n1 = 14;
n2 = 8;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
n1 = 10;
n2 = 22;
t = tree.lca(tree.root, n1, n2);
Console.WriteLine(
"LCA of " + n1 + " and " + n2
+ " is " + t.data);
}
}
// This code is contributed by Shrikant13
上述解决方案的时间复杂度为O(h),其中h是树的高度。
上述解决方案的空间复杂度是恒定的。
上面的函数假定n1和n2都在BST中。如果n1和n2不存在,则它们可能返回不正确的结果。如果n1或n2或两者都不存在于BST中,则扩展上述解决方案以返回NULL。