1 """
2 Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
3 According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
4 Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
5 Example 1:
6 Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
7 Output: 3
8 Explanation: The LCA of nodes 5 and 1 is 3.
9 Example 2:
10 Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
11 Output: 5
12 Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
13 """
14 """
15 本题两种解法。第一种非递归的方法
16 用queue来存储结点遍历
17 用dict{root, parent[root]}来存储每个结点的父亲结点
18 然后用一个set存储p的所有父辈结点
19 再遍历q的每个父亲结点查找是否再set中
20 如果找到即为p,q结点的最近公共祖先
21 """
22 class TreeNode:
23 def __init__(self, x):
24 self.val = x
25 self.left = None
26 self.right = None
27
28 class Solution1:
29 def lowestCommonAncestor(self, root, p, q):
30 queue = [root] #用来层次遍历
31 parent = {root: None} #用dict存储父亲结点
32 while queue:
33 node = queue.pop()
34 if node.left:
35 parent[node.left] = node #存父亲结点
36 queue.append(node.left) #入队
37 if node.right:
38 parent[node.right] = node
39 queue.append(node.right)
40 res = set() #set集合是一个无序不重复元素的序列
41 while p: #res=() 这是把res定义为tuple,tuple是只能查看的list
42 res.add(p) #将p的所有父辈结点放入set里
43 p = parent[p]
44 while q not in res: #q向上找到相同的父亲结点
45 q = parent[q]
46 return q
47
48 """
49 第二种是递归写法:没有理解
50 传送门:https://blog.csdn.net/qq_17550379/article/details/95903394
51 树型问题首先考虑递归,对于每个树中的p和q只会有一下几种情况
52 1. p在左子树中,q在右子树中
53 2. q在左子树中,p在右子树中
54 3. p和q都在左子树中
55 4. p和q都在右子树中
56 对于第一种和第二种情况很简单,p和q的最近公共祖先就是root。
57 对于第三种情况我们只需递归向左子树找,第四种情况我们只需递归向右子树找。接着思考边界情况。
58 当p==root or q==root的时候,我们返回root即可(因为要找最近公共祖先,继续遍历的话,就不可能是其祖先了)。
59 那么这里就有一个迷惑人的地方了,请认真思考第一种和第二种情况下,左右子树的递归返回结果是什么?就是p和q。
60 """
61
62 class Solution2:
63 def lowestCommonAncestor(self, root, p, q):
64 if not root or root == p or root == q:
65 return root
66 left = self.lowestCommonAncestor(root.left, p, q)
67 right = self.lowestCommonAncestor(root.right, p, q)
68 if left and right:
69 return root
70 return left if left else right