二叉树最低公共祖先
来源:互联网 发布:淘宝付邮试用中心入口 编辑:程序博客网 时间:2024/06/06 02:01
在笔试中遇到了二叉树最低公共祖先的问题,现在将这个问题彻底地总结一下。其实相关问题还不少,比如二叉树是BST还是普通二叉树,二叉树存在指向父结点的指针吗?
1.二叉搜索树的情况,这样的情景下处理比较简单一些,前序遍历该二叉树,如果当前结点的值比两个所求结点大,则最低公共祖先肯定存在于当前结点的左子树中,如果当前结点的值比两个所求结点小,则最低公共祖先肯定存在于当前结点的右子树中,否则,当前结点即为所求LC.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */public class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root != null) { if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right,p,q); else if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left,p,q); else return root; } return null; }}
2.如果为普通二叉树且没有指向父结点的指针呢?如果可以使用辅助内存,可以把搜索所求结点的遍历路径保存下来,比如,放在ArrayList中,第一个相同结点即为LCA.如果不能使用辅助内存,就要使用难一点的递归求解了我。下面是整个过程的代码,可以在eclipse中单步运行查看过程,会理解得稍微深刻一些。
package com.leetcode.BinaryTree;import java.util.ArrayList;import java.util.Stack;import com.nowcoder.TreeImp;/** * Created by yanglei 2017-3-22 */public class MyBinaryTree {// private TreeNode root=null; /* * */ public MyBinaryTree(){ root=new TreeNode(1,"root(3)"); } /** * * */ public void createBTree(){ TreeNode newNode5=new TreeNode(2,"5"); TreeNode newNode1=new TreeNode(3,"1"); TreeNode newNode6=new TreeNode(4,"6"); TreeNode newNode2=new TreeNode(5,"2"); TreeNode newNode0=new TreeNode(6,"0"); TreeNode newNode8=new TreeNode(7,"8"); TreeNode newNode7=new TreeNode(8,"7"); TreeNode newNode4=new TreeNode(9,"4"); root.left=newNode5; root.right=newNode1; root.left.left=newNode6; root.left.right=newNode2; root.right.right=newNode8; root.right.left=newNode0; root.left.right.left=newNode7; root.left.right.right=newNode4; } public TreeNode getRoot(){ return root; } public int getHeight(TreeNode subTree){ return height(subTree); } private int height(TreeNode node) { if(node==null) return 0; else { int l=height(node.left); int r=height(node.right); return (l<r)?(r+1):(l+1); } } public int getSize(TreeNode subTree){ return size(subTree); } private int size(TreeNode node) { if(node==null) return 0; else{ return 1+size(node.left) +size(node.right); } } /** * * @param subTree * @param node * @return */ public TreeNode getParent(TreeNode subTree,TreeNode node){ if(subTree==null) return null; if(subTree.left==node || subTree.right==node) return subTree; TreeNode p; if((p=getParent(subTree.left,node))!=null) return p; else return getParent(subTree.right,node); } public void preOrder(TreeNode subTree){ if(subTree==null) return; else{ visit(subTree); preOrder(subTree.left); preOrder(subTree.right); } } public void inOrder(TreeNode subTree){ if(subTree==null) return; else{ inOrder(subTree.left); visit(subTree); inOrder(subTree.right); } } public void postOrder(TreeNode subTree){ if(subTree==null) return; else{ postOrder(subTree.left); postOrder(subTree.right); visit(subTree); } } public void nonRecPreOrder(TreeNode subTree){ Stack<TreeNode> stack=new Stack<>(); TreeNode p=subTree; while(p!=null||stack.size()>0){ while(p!=null){ visit(p); stack.push(p); p=p.left; } if(stack.size()>0){ p=stack.pop(); p=p.right; } } } public void nonRecInOrder(TreeNode subTree){ Stack<TreeNode> stack=new Stack<>(); TreeNode p=subTree; while(p!=null || stack.size()>0){ while(p!=null){ stack.push(p); p=p.left; } if(stack.size()>0){ p=stack.pop(); visit(p); p=p.right; } } } public void nonRecPostOrder(TreeNode subTree){ Stack<TreeNode> stack=new Stack<>(); TreeNode p=subTree; TreeNode node=null; while(p!=null){ for(;p.left!=null;p=p.left) stack.push(p); while(p!=null&&p.right==null||p.right==node){ visit(p);// node=p; if(stack.size()==0) return;// p=stack.pop(); } stack.push(p); p=p.right; } } /** * * @param node */ private void visit(TreeNode node){ node.isVisited=true; System.out.println("NodeValue: "+node.data+",key="+node.key); } /** * */ private class TreeNode { public boolean isVisited=false; private String data=""; public TreeNode left=null; public TreeNode right=null; private int key=0; private boolean rVisited=false; public TreeNode(int key,String data){ this.key=key; this.data=data; } } public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == null || p == null || q == null) return null; ArrayList<TreeNode> p_Path = new ArrayList<TreeNode>(); ArrayList<TreeNode> q_Path = new ArrayList<TreeNode>(); getPath(root,p,p_Path); getPath(root,q,q_Path); for (int i = 0;i < p_Path.size() && i < q_Path.size();i++) { if (p_Path.get(i).data == q_Path.get(i).data) return p_Path.get(i); } return null; } public Boolean getPath(TreeNode root2, TreeNode p, ArrayList<TreeNode> p_Path) { if (root2 == null || p == null) return null; if (root2 == p) return true; if (root2.left != null) { p_Path.add(root2.left); if (getPath(root2.left,p,p_Path)) return true; p_Path.remove(p_Path.size() - 1); } if (root2.right != null) { p_Path.add(root2.right); if (getPath(root2.right,p,p_Path)) return true; p_Path.remove(p_Path.size() - 1); } return false; } /* 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!=null&&right!=null) return root; return left == null ? right : left; } */ public static void main(String[] args) { MyBinaryTree mt = new MyBinaryTree(); TreeNode root1 = mt.root; MyBinaryTree pq = new MyBinaryTree(); mt.createBTree(); // mt.preOrder(root1); TreeNode pTest = root1.left.left; TreeNode qTest = root1.left.right.left; TreeNode resultNode = mt.lowestCommonAncestor(root1, pTest, qTest); System.out.println(resultNode.data.toString()); }}
1 0
- 二叉树最低公共祖先
- 二叉搜索树的最低公共祖先
- 树最低公共祖先
- 二叉树两结点的最低公共祖先结点(一)
- 二叉搜索树两结点最低公共祖先结点
- 二叉树两结点最低公共祖先结点(二)
- 二叉树两个结点的最低公共祖先
- 二叉树两个结点的最低公共祖先
- 二叉树中两个结点的最低公共祖先
- 面试经典(5)--二叉树最低公共祖先LCA
- 二叉树的最低公共祖先(剑指offer)
- 二叉树中查找两个节点的最低公共祖先
- 编程算法 - 二叉树的最低公共祖先 代码(C)
- 寻找二叉树两个节点的最低公共祖先(LCA)
- 算法面试——二叉树最低公共祖先LCA
- 求二叉树中两个节点的最低公共祖先
- 二叉树 之 lowest common ancestor 最低公共祖先
- 寻找二叉树两个节点的最低公共祖先
- 回文数字
- 非搜索二叉树的最近公共祖先
- IO高级应用-BufferedReader
- 设计模式/面向对象
- Tram 【最短路径】
- 二叉树最低公共祖先
- 剑指Offer 18 树的子结构
- vim使用总结
- 我是怎么走出迷茫,找到自己热爱的事业的。
- Python变量和数据类型
- HTML+CSS基础笔记——标签篇
- Runnable和Thread的使用简介与区别
- 【TV Picture Quality
- [mysql]MySQL修改root密码的多种方法