BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / acm-icpc / #88539同步于 2015/12/10
该镜像源已超过 30 天没有更新,可能在源站已被删除。
ACM_ICPC机器人发帖

LeetCode 236题 Lowest Common Ancestor of a Binary Tree

sun111
2015/12/10镜像同步6 回复
此题是求一棵二叉树的两个节点的最近公共祖先,我是考虑先用DFS来得到这两个指定节点的路径,保存在List中,然后对这两个list,进行逐一比较,如果得到最先公共祖先。代码如下: Class TreeNode { TreeNode left; TreeNode right; int val; TreeNode(int x) { val = x; } } public class Solution { public static TreeNode lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q) { Stack<TreeNode> path = new Stack<TreeNode>(); List<List<TreeNode>> result = new ArrayList<List<TreeNode>>(); path(root,p,path,result); path.removeAllElements(); path(root,q,path,result); System.out.println(result.size()); List<TreeNode> l1 = result.get(0); List<TreeNode> l2 = result.get(1); System.out.println(l1.size() + " " + l2.size()); int length = l1.size() < l2.size() ? l1.size() : l2.size(); System.out.println(length); TreeNode node = null; while(length -- > 0) { if(l1.get(length).val == l2.get(length).val) { node = l1.get(length); break; } //length--; } System.out.println(node.val); return node; } @SuppressWarnings("unchecked") public static boolean path(TreeNode root,TreeNode node,Stack<TreeNode> path,List<List<TreeNode>> result) { if(root == null) return false; path.push(root); if(root.val == node.val) { result.add((Stack<TreeNode>)(path.clone())); return true; } if(path(root.left,node,path,result)) return true; if(path(root.right,node,path,result)) return true; path.pop(); return false; } /*public static void main(String[] args) { TreeNode root = new TreeNode(5); TreeNode l1 = new TreeNode(7); TreeNode r1 = new TreeNode(8); TreeNode l11 = new TreeNode(9); TreeNode r11 = new TreeNode(10); root.left = l1; root.right = r1; l1.left = l11; l1.right = null; r1.left = r11; r1.right = null; lowestCommonAncestor(root,l11,r1); }*/ //测试用的 } 上面的代码基本的例子是可以过的吗,但是放在Leetcode上一跑,发现出现了栈溢出的情况,就是因为节点一多,递归的时候会将很多中间节点保存在栈中,就会出现这个问题,就问大神们如何改这个代码,最好别改我的思路。
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
inaadversity机器人#1 · 2015/12/11
这么写呢 int dfs(tree *root,tree *target1,tree *target2,tree **result){ if(root == NULL) return 0; if(root == target1 || root == target2) return 1; int ret = dfs(root->left,target1,target2,result); ret += dfs(root->right,target1,target2,result); if(ret == 2){ //找到最近公共祖先 *result = root; return 0; } return ret; } treenode *ret; dfs(root,p1,p2,&ret); // ret 为答案 【 在 sun111 的大作中提到: 】 : 此题是求一棵二叉树的两个节点的最近公共祖先,我是考虑先用DFS来得到这两个指定节点的路径,保存在List中,然后对这两个list,进行逐一比较,如果得到最先公共祖先。代码如下: : Class TreeNode : { : ...................
sun111机器人#2 · 2015/12/11
【 在 inaadversity 的大作中提到: 】 : 这么写呢 : [code=c] : int dfs(tree *root,tree *target1,tree *target2,tree **result){ : ................... 看C++有点累,仁兄能讲下大致思路吗?
inaadversity机器人#3 · 2015/12/11
两个节点在公共祖先的两个分支上 后序遍历,如果遇到target之一,就返回1,遇到空返回0 如果在某个节点处,左右分支各返回1,那这个节点就是最近公共祖先,把公共祖先的位置记录下来,返回0。 static TreeNode result; static int dfs(TreeNode root,TreeNode target1,TreeNode target2){ if(root == null) return 0; if(root == target1 || root == target2) return 1; int ret = dfs(root.left, target1, target2); ret += dfs(root.right, target1, target2); if(ret == 2){ result = root; return 0; } return ret; } 【 在 sun111 的大作中提到: 】 : 看C++有点累,仁兄能讲下大致思路吗?
sun111机器人#4 · 2015/12/11
【 在 inaadversity 的大作中提到: 】 : 两个节点在公共祖先的两个分支上 : 后序遍历,如果遇到target之一,就返回1,遇到空返回0 : 如果在某个节点处,左右分支各返回1,那这个节点就是最近公共祖先,把公共祖先的位置记录下来,返回0。 : ................... 恩,我再想下用java实现下
stevesun机器人#5 · 2015/12/11
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root==null){ return null; } if(p==root||q==root){ return root; } TreeNode l = lowestCommonAncestor(root.left,p,q); TreeNode r = lowestCommonAncestor(root.right,p,q); if(l!=null&&r!=null){ return root; } return (l!=null)?l:r; }
rancho机器人#6 · 2015/12/11
发现了另一个问题: public static boolean path(TreeNode root,TreeNode node,Stack<TreeNode> path,List<List<TreeNode>> result) { if(root == null) return false; path.push(root); if(root.val == node.val) { result.add((Stack<TreeNode>)(path.clone())); return true; } if(path(root.left,node,path,result)) return true; if(path(root.right,node,path,result)) return true; path.pop(); return false; } } 判断两个节点是否相同,你用其val域判断,但是有可能测例中有val一样的节点。 如果是这样的话,那么就会有错误结果。 看了你的递归,你把List<List<TreeNode>> result我猜这个变量也作为参数传进去,往栈里面放很占空间(因为你List里面套了List),我试着只用了一层List。很容易就过了。 也许你应该用没过的测例试一下。 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { LinkedList<TreeNode> stack1 = new LinkedList<TreeNode>();//The path for p; LinkedList<TreeNode> stack2 = new LinkedList<TreeNode>();//The path for q; search(root, p, stack1); search(root, q, stack2); TreeNode node1 = stack1.pollLast(); TreeNode node2 = stack2.pollLast(); TreeNode res = null; while(node1 == node2){ res = node1; node1 = stack1.pollLast(); node2 = stack2.pollLast(); } return res; } private boolean search(TreeNode root, TreeNode node, LinkedList<TreeNode> stack){ if(root != null) stack.push(root); else return false; if(node == root){ return true; } if(search(root.left, node, stack)) return true; if(search(root.right, node, stack)) return true; stack.pop(); return false; } 【 在 sun111 的大作中提到: 】 : 此题是求一棵二叉树的两个节点的最近公共祖先,我是考虑先用DFS来得到这两个指定节点的路径,保存在List中,然后对这两个list,进行逐一比较,如果得到最先公共祖先。代码如下: : Class TreeNode : { : ...................