题目:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
(所有节点的值都是唯一的。p、q 为不同节点且均存在于给定的二叉树中。)
leetcode原题链接
思路:
看下图的示例2
p=5,q=4,公共节点A=5
从根节点到p节点的路径:3-5
从根节点到q节点的路径:3-5-2-4
可以发现:
- 公共祖先:两个节点的公共祖先一定在 从根节点到这两个节点的路径上
- 最近:同时出现在 这两条路径上,离根节点最远/离这两个节点最近
求法:
- 求p节点路径
- 求q节点路径
- 求两条路径上最后一个相同的节点
第一步和第二步,均为:求【从根节点到某节点的路径DFS】
从根节点 遍历到该节点,找到该节点后 结束搜索
将遍历过程中遇到节点指针 按循序存储到栈中
从根节点到该节点的路径:从栈底到栈顶存储的节点指针
代码:
报错代码1:
object of type ‘NoneType’ has no len()
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
#
# @param root TreeNode类
# @param p TreeNode类
# @param q TreeNode类
# @return TreeNode类
#
class Solution:
global res
res=[]
def nearestCommonAncestor(self , root , p , q ):
# write code here
if root is None or p is None or q is None:
return None
res1=self.DFS(root,p)
res2=self.DFS(root,q)
l=min(len(res1),len(res2))
for i in range(0,l):
if res1[i]!=res2[i]:
return res1[i-1]
def DFS(self,node,search):
if node is None:#如果当前节点是null
return
res.append(node)#读入当前节点,入一个临时栈
if node.val==search.val:
return res
self.DFS(node.left,search)
self.DFS(node.right,search)
#运行到这里证明,当前节点node的左节点和右节点的遍历均已完成,仍为找到目标节点
#证明当前节点一定不在 根节点到目标节点 的路径中,我们需要把当前节点从res中弹出,往回退一步,遍历另一条路径
res.pop()#弹出当前节点
报错代码2:
在1的基础上改动,将res也作为一个参数 传入DFS函数中
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if root is None:
return None
res1=[]
res2=[]
self.DFS(root,p,res1)
self.DFS(root,q,res2)
l=min(len(res1),len(res2))
for i in range(0,l):
if res1[i].val!=res2[i].val:
return res1[i-1]
def DFS(self,node,search,res):
if node is None:#如果当前节点是null
return
res.append(node)#读入当前节点,入一个临时栈
if node==search:
return res
self.DFS(node.left,search,res)
self.DFS(node.right,search,res)
#运行到这里证明,当前节点node的左节点和右节点的遍历均已完成,仍为找到目标节点
#证明当前节点一定不在 根节点到目标节点 的路径中,我们需要把当前节点从res中弹出,往回退一步,遍历另一条路径
res.pop()#弹出当前节点
再改代码
把res1和res2 print出来,p和q的路径不对