题解 | #在二叉树中找到两个节点的最近公共祖先#
在二叉树中找到两个节点的最近公共祖先
http://www.nowcoder.com/practice/e0cc33a83afe4530bcec46eba3325116
思路:遍历二叉树,两个结点最近公共祖先存在几种情况:
- 节点的左右子结点分别是给定o1和o2的值,祖先为root
- 节点的左节点是o1或o2的值,其后代包含另一个给定(o2或o1)的值,祖先为root的左节点
- 节点的右节点是o1或o2的值,其后代包含另一个给定(o2或o1)的值,祖先为root的右节点
- 节点的左/右节点是o1或o2的值,其后代不包含另一个给定的值,祖先为root
package main
import . "nc_tools"
/*
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
func lowestCommonAncestor( root *TreeNode , o1 int , o2 int ) int {
//标记
if root == nil {
return -1
}
// write code here
if (root.Val == o1 && isChildNode(root, o2)) || (root.Val == o2 && isChildNode(root, o1)) {
return root.Val
}
if root.Left != nil {
//root节点的左子节点值等于o1或o2,若另一个节点是该节点后代,祖先为root的左子结点;若不是该结点后代,则祖先为root
if (root.Left.Val == o1 && !isChildNode(root.Left, o2)) || (root.Left.Val == o2 && !isChildNode(root.Left, o1)) {
return root.Val
}
if (root.Left.Val == o1 && isChildNode(root.Left, o2)) || (root.Left.Val == o2 && isChildNode(root.Left, o1)) {
return root.Left.Val
}
}
if root.Right != nil {
//同上,右
if (root.Right.Val == o1 && isChildNode(root.Right, o2)) || (root.Right.Val == o2 && isChildNode(root.Right, o1)) {
return root.Right.Val
}
if (root.Right.Val == o1 && !isChildNode(root.Right, o2)) || (root.Right.Val == o2 && !isChildNode(root.Right, o1)) {
return root.Val
}
}
//递归查找,如果有结果就直接返回,不必继续执行
commonAncestor1 := lowestCommonAncestor(root.Left, o1, o2)
if commonAncestor1 != -1 {
return commonAncestor1
}
commonAncestor2 := lowestCommonAncestor(root.Right, o1, o2)
return commonAncestor2
}
//传入根节点和目标值,用于判断目标值的节点是否是根节点的后代
func isChildNode(root *TreeNode, node int) bool {
if root.Left != nil && root.Left.Val == node {
return true
}
if root.Right != nil && root.Right.Val == node {
return true
}
if root.Left !=nil && isChildNode(root.Left, node) {
return true
}
if root.Right != nil && isChildNode(root.Right, node) {
return true
}
return false
}