二叉树两节点之间的最短距离
给定一个二叉树, 找到该树中两个指定节点间的最短距离
// A
// B C
//D E F
// D E --> 2
// E F --> 4
解法一:先求两节点的最近公共祖先,然后层序遍历求三个节点所在位置的深度,然后距离加减就行
func main() { //按数组层序建立二叉树 root:=createTree(0,[]int{1,2,3,4,5,6}) //求公共祖先 lca:=lowestCommonAncestor(root,root.Left,root.Right.Left) fmt.Println(Getdist(root,root.Left,root.Right.Left,lca)) } type TreeNode struct { Val int Left *TreeNode Right *TreeNode } // 按数组建立二叉树 func createTree(index int,nums []int) *TreeNode{ if index>=len(nums){ return nil } root:=&TreeNode{ Val: nums[index], } root.Left=createTree(index*2+1,nums) root.Right=createTree(index*2+2,nums) return root } //求最近公共祖先节点 func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { if root==nil{ return nil } if root.Val==p.Val||root.Val==q.Val{// 如果p,q为根节点,则公共祖先为根节点 return root } if find(root.Left,p)&&find(root.Left,q){// 如果p在左子树,并且q也在左子树,则在左子树查找公共祖先 return lowestCommonAncestor(root.Left,p,q) } if find(root.Right,p)&&find(root.Right,q){ return lowestCommonAncestor(root.Right,q,p)//如果p在右子树,并且q也在右子树,则在右子树查找公共祖先 } return root // 如果p,q分属两侧,则公共祖先为根节点 } //层序遍历求三个节点之间的距离 func Getdist(root,q,p,lca *TreeNode) int{ que:=make([]*TreeNode,0) que=append(que,root) vis:=make([]int,3) depth:=0 for len(que)!=0{ size:=len(que) for i:=0;i<size;i++{ front:=que[0] que=que[1:] if front==q{ vis[0]=depth } if front==p{ vis[1]=depth } if front==lca{ vis[2]=depth } if front.Left!=nil{ que=append(que,front.Left) } if front.Right!=nil{ que=append(que,front.Right) } } depth++ } return vis[0]+vis[1]-vis[2] }
递归遍历二叉树,根据要寻找两个目标节点q,p和root节点的位置,分情况计算距离。
一、递归树的最小子结构,root、left、right节点
二、q,p节点中的一个为root节点(假设是q),那么q,p的距离就是p节点所在树的高度
三、q,p节点分别在root节点的左右子树中,那么q,p的距离就是两节点递归深度之和
func findDist(root,q,p *TreeNode,ans *int) int{ if root==nil{ return 0 } left:=findDist(root.Left,q,p,ans) right:=findDist(root.Right,q,p,ans) if root==p||root==q{//root节点是q、p节点只其中一个,在继续判断子树是否存在另一个节点,并且q,p的距离就是高度差 if left!=0{ *ans=left return 0 } if right!=0{ *ans=right return 0 } return 1 } if left!=0&&right!=0{//q、p节点分别出现在左右两个子树 *ans=left+right return 0 } if left==0&&right==0{//p,q节点不在当前左右子树 return 0 } if left!=0{ //左子树出现目标节点,递归深度+1 return left+1 } return right+1 }
等风起的那一天,我已准备好一切