@@ -103,9 +103,9 @@ public class LastSameInTreeParent {
103103
104104```
105105
106- ## 普通树 ,没有指向父结点的指针
106+ ## 普通二叉树 ,没有指向父结点的指针
107107
108- 这道题再加大难度,如果没有指向父结点的指针呢?是否还能转换成两个链表的第一个公共结点来解决?
108+ 这道题再加大难度,如果没有指向父结点的指针呢?
109109
110110想办法创造链表。两个输入结点如果在树中存在,那么** 从根结点开始向下的某条路径中必然包含这个结点** ,使用两个链表分别保存包含这两个结点的路径。这样就可以把问题转换成求两个链表的第一个公共结点了。
111111
@@ -130,23 +130,28 @@ public class LastSameInTree {
130130
131131 LinkedList<Node > path1 = new LinkedList<> ();
132132 LinkedList<Node > path2 = new LinkedList<> ();
133- collectNode(root, a, path1);
134- collectNode(root, b, path2);
133+
134+ LinkedList<Node > res1 = new LinkedList<> ();
135+ LinkedList<Node > res2 = new LinkedList<> ();
136+ collectNode(root, a, path1, res1);
137+ collectNode(root, b, path2, res2);
135138 return getLastSameNode(path1, path2);
136139 }
137140
138141 /**
139142 * 收集含有结点node的路径上的所有结点,形成一条链表
140143 */
141- private boolean collectNode (Node root , Node node , LinkedList<Node > path ) {
142- if (root == node) return true ;
144+ private void collectNode (Node root , Node node , LinkedList<Node > path , LinkedList< Node > res ) {
145+ if (root == null || node == null ) return ;
143146 path. add(root);
147+ if (root = node) {
148+ res. addAll(path);
149+ }
144150 for (Node child : root. children) {
145- if (collectNode(child, node, path)) return true ;
151+ if (collectNode(child, node, path));
146152 }
147153 // 该条路径上没找到结点node就要从路径中移除
148- path. removeLast();
149- return false ;
154+ path. remove(path. size() - 1 );
150155 }
151156
152157 /**
@@ -172,6 +177,25 @@ public class LastSameInTree {
172177
173178---
174179
180+
181+ 普通二叉树的递归解法
182+
183+ 来自[ LeetCode] ( https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/ )
184+
185+ ``` java
186+ class Solution {
187+ public TreeNode lowestCommonAncestor (TreeNode root , TreeNode p , TreeNode q ) {
188+ if (root == null ) return null ; // 如果树为空,直接返回null
189+ if (root == p || root == q) return root; // 如果 p和q中有等于 root的,那么它们的最近公共祖先即为root(一个节点也可以是它自己的祖先)
190+ TreeNode left = lowestCommonAncestor(root. left, p, q); // 递归遍历左子树,只要在左子树中找到了p或q,则先找到谁就返回谁
191+ TreeNode right = lowestCommonAncestor(root. right, p, q); // 递归遍历右子树,只要在右子树中找到了p或q,则先找到谁就返回谁
192+ if (left == null ) return right; // 如果在左子树中 p和 q都找不到,则 p和 q一定都在右子树中,右子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
193+ else if (right == null ) return left; // 否则,如果 left不为空,在左子树中有找到节点(p或q),这时候要再判断一下右子树中的情况,如果在右子树中,p和q都找不到,则 p和q一定都在左子树中,左子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
194+ else return root; // 否则,当 left和 right均不为空时,说明 p、q节点分别在 root异侧, 最近公共祖先即为 root
195+ }
196+ }
197+ ```
198+
175199by @sunhaiyu
176200
1772012018.2.14
0 commit comments