二叉树最近公共父节点大致分为两种,一种是二叉查找树,另一种是普通二叉树,相对来说二叉查找树更简单,因为我们能利用二叉查找树的特性来更快的找到最近公共父节点
自己构造的树节点类
data class TreeNode(
val left: TreeNode? = null,
val right: TreeNode? = null,
val value: Int = 0
)
二叉查找树的最近公共父节点
目标二叉查找树:
val node =
TreeNode(
TreeNode(
TreeNode(TreeNode(value = 3), TreeNode(value = 5), 4),
TreeNode(TreeNode(value = 8), TreeNode(value = 10), 9),
7),
TreeNode(
TreeNode(TreeNode(value = 13), TreeNode(value = 16), 15),
TreeNode(TreeNode(value = 17), TreeNode(value = 21), 20),
18),
12)
查找算法
主要利用了每个节点的左节点都小于自己,每个右节点都大于自己的特性,递归查找目标节点
fun getNearestCommonAncestorInBinarySearchTree(node: TreeNode?, one: TreeNode, another: TreeNode): TreeNode? {
if (node == null || node.value == one.value || node.value == another.value) return node
if (node.value > one.value && node.value > another.value) return getNearestCommonAncestorInBinarySearchTree(node.left, one, another)
if (node.value < one.value && node.value < another.value) return getNearestCommonAncestorInBinarySearchTree(node.right, one, another)
return node
}
二叉树的最近公共父节点
目标二叉查找树:
val node =
TreeNode(
TreeNode(
TreeNode(TreeNode(value = 55), TreeNode(value = 12), 35),
TreeNode(TreeNode(value = 85), TreeNode(value = 79), 46),
72),
TreeNode(
TreeNode(TreeNode(value = 1), TreeNode(value = 23), 42),
TreeNode(TreeNode(value = 4), TreeNode(value = 99), 502),
64),
89)
查找算法
二叉树没有上面的查找树的特性,需要其他判断。只要最终判断一个节点在某个节点的左侧,另一个在其右侧,则该节点为目标节点
fun getNearestCommonAncestorInBinaryTree(node: TreeNode?, one: TreeNode, another: TreeNode): TreeNode? {
if (node == null || node.value == one.value || node.value == another.value) return node
val left = getNearestCommonAncestorInBinaryTree(node.left, one, another)
val right = getNearestCommonAncestorInBinaryTree(node.right, one, another)
if (left != null && right != null) return node
return left ?: right
}