leetcode236 Lowest Common Ancestor of a Binary Tree

 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

 

posted @ 2020-02-13 22:12  yawenw  阅读(100)  评论(0编辑  收藏  举报