leetcode236

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL || root == p || root == q)
        {
            return root;
        }
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if (left && right)
        {
            return root;
        }
        else
        {
            return left == NULL ? right : left;
        }
    }
};

 补充一个DFS实现,使用先序遍历将每一个路径都记录下来,然后分情况讨论。

 1 public class Solution
 2     {
 3         List<List<TreeNode>> V = new List<List<TreeNode>>();
 4         Stack<TreeNode> v = new Stack<TreeNode>();
 5 
 6         public void PostTree(TreeNode node)
 7         {
 8             if (node != null)
 9             {
10                 v.Push(node);
11                 if (node.left != null)
12                 {
13                     PostTree(node.left);
14                     v.Pop();
15                 }
16                 if (node.right != null)
17                 {
18                     PostTree(node.right);
19                     v.Pop();
20                 }
21                 if (node.left == null && node.right == null)
22                 {
23                     var list = new List<TreeNode>();
24                     foreach (var s in v)
25                     {
26                         list.Add(s);
27                     }
28                     list.Reverse();
29                     V.Add(list);
30                 }
31 
32             }
33         }
34 
35         public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
36         {
37             PostTree(root);
38             int p_index = -1;
39             int q_index = -2;
40             for (var i = 0; i < V.Count(); i++)
41             {
42                 if (V[i].Find(x => x.val == p.val) != null)
43                 {
44                     p_index = i;
45                 }
46                 if (V[i].Find(x => x.val == q.val) != null)
47                 {
48                     q_index = i;
49                 }
50                 if (p_index >= 0 && q_index >= 0)
51                 {
52                     break;
53                 }
54             }
55             if (p_index == q_index)
56             {
57                 var l = V[p_index];
58                 //p和q在同一个路径上
59                 foreach (var va in l)
60                 {
61                     if (va.val == p.val || va.val == q.val)
62                     {
63                         return va;
64                     }
65                 }
66             }
67             else
68             {
69                 //p和q在不通路径上
70                 var l1 = V[p_index];
71                 var l2 = V[q_index];
72                 int i = 0;
73                 int j = 0;
74                 while (i < l1.Count() && j < l2.Count())
75                 {
76                     if (l1[i].val != l2[j].val)
77                     {
78                         return l1[i - 1];
79                     }
80                     i++;
81                     j++;
82                 }
83             }
84             return null;
85         }
86     }

补充一个python的实现:

 1 class Solution:
 2     #当p和q分别在某节点的左子树和右子树的时候,这个节点就是LCA
 3     def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
 4         if root == None or root == p or root == q:
 5             return root
 6         left = self.lowestCommonAncestor(root.left,p,q)#在左子树中找p或q
 7         right = self.lowestCommonAncestor(root.right,p,q)#在右子树中找p或q
 8         if left != None and right != None:#p和q分别在这个节点的左右子树,则当前节点就是LCA
 9             return root
10         elif left != None:#p和q都在这个节点的左子树,则在p和q中,先被找到的就是LCA
11             return left
12         elif right != None:#p和q都在这个节点的右子树,则先被找到的就是LCA
13             return right
14         else:
15             return None#p和q不在这个节点的子树中

LCA让我想起了日月生辉的光辉战斗机。

原文地址:https://www.cnblogs.com/asenyang/p/9747674.html