1. 程式人生 > >面試題之樹中兩個節點的最低公共祖先節點

面試題之樹中兩個節點的最低公共祖先節點

1.樹為二叉搜尋樹,二叉搜尋樹特點:值:右>根>左

①思路

從根節點開始遍歷

a:若該節點值比所給兩個節點均大,則公共祖先節點必在其左子樹上,遍歷其左子樹。

b:若該節點值比所給兩個節點均小,則公共祖先節點必在其右子樹上,遍歷其右子樹。

c:直到找到一個節點,位於兩節點的中間。

Given a binary search tree(BST),find the lowest common ancestor(LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia:"The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself)."


For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6.Another example is LCA of nodes 2 and 4 is 2,since a node can be a descendant of itself according to the LCA definition.

②程式碼

public class BanarySearchTreeMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeNode root = initTree();
		TreeNode result = lowestCommonAncestor(root, new TreeNode(2), new TreeNode(4));
		System.out.println(result.val);
	}
	/*
	 * 初始化二叉搜尋樹,其特點:右>根>左;
	 */
	private static TreeNode initTree(){
		TreeNode root = new TreeNode(6);
		TreeNode node0 = new TreeNode(0);
		TreeNode node2 = new TreeNode(2);
		TreeNode node3 = new TreeNode(3);
		TreeNode node4 = new TreeNode(4);
		TreeNode node5 = new TreeNode(5);
		TreeNode node7 = new TreeNode(7);
		TreeNode node8 = new TreeNode(8);
		TreeNode node9 = new TreeNode(9);
		root.left = node2;
		root.right = node8;
		node2.left = node0;
		node2.right = node4;
		node8.left = node7;
		node8.right = node9;
		node4.left = node3;
		node4.right = node5;
		
		return root;
	}
	/*
	 * 二叉搜尋樹最低公共父節點
	 */
	private static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		if(root==null||root==p||root==q) {
			return root;
		}
		if(root.val>p.val&&root.val>q.val) {
			return lowestCommonAncestor(root.left, p, q);
		}
		if(root.val<p.val&&root.val<q.val) {
			return lowestCommonAncestor(root.right, p, q);
		}else {
			return root;
		}
	}
	
	
}

class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;
	TreeNode(int x) {
		val = x;
	}

}

2.樹為普通二叉樹

①思路

a:遍歷左子樹,若與兩節點中某值相等或左右均不為null,則返回根節點,否則,繼續遍歷;

b:遍歷右子樹,若與兩節點中某值相等或左右均不為null,則返回根節點,否則,繼續遍歷;

c:返回節點;

For example,the lowest common ancestor (LCA) of nodes 5 and 1 is 3.Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

②程式碼

public class CommonTreeMain {

	public static void main(String[] args) {
		TreeNode root = initTree();
		TreeNode result = lowestCommonAncestor(root, new TreeNode(5), new TreeNode(4));
		
		System.out.println(result.val);
	}
	
	private static TreeNode initTree(){
		TreeNode root = new TreeNode(3);
		TreeNode node0 = new TreeNode(0);
		TreeNode node1 = new TreeNode(1);
		TreeNode node2 = new TreeNode(2);
		TreeNode node4 = new TreeNode(4);
		TreeNode node5 = new TreeNode(5);
		TreeNode node6 = new TreeNode(6);
		TreeNode node7 = new TreeNode(7);
		TreeNode node8 = new TreeNode(8);
		root.left = node5;
		root.right = node1;
		node5.left = node6; 
		node5.right = node2; 
		node1.left = node0;
		node1.right = node8;
		node2.left = node7;
		node2.right = node4;
		return root;
	}
	
	/*
	 * 查詢最低公共祖先節點
	 */
    private static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {  
        if(root==null||root.val==p.val||root.val==q.val)  
            return root;  
        TreeNode left = lowestCommonAncestor(root.left,p,q);  
        TreeNode right = lowestCommonAncestor(root.right,p,q);  
        if (left == null)   
            return right;  
        if (right == null)   
            return left;  
        return root;  
    }  
}

③迭代演算法:

需要我們儲存下由root根節點到p和q節點的路徑,並且將路徑存入list中,則問題轉化為求兩個list集合的最後一個共同元素。

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {    
            if(root==null || p==null || q==null)   
                return null;  
            List<TreeNode> pathp = new ArrayList<>();    
            List<TreeNode> pathq = new ArrayList<>();    
            pathp.add(root);    
            pathq.add(root);    
                
            getPath(root, p, pathp);    
            getPath(root, q, pathq);    
                
            TreeNode lca = null;    
            for(int i=0; i<pathp.size() && i<pathq.size(); i++) {    
                if(pathp.get(i) == pathq.get(i))   
                    lca = pathp.get(i);    
                else   
                    break;    
            }    
            return lca;    
        }    
            
        private boolean getPath(TreeNode root, TreeNode n, List<TreeNode> path) {    
            if(root==n)     
                return true;    
              
            if(root.left!=null) {    
                path.add(root.left);    
                if(getPath(root.left, n, path))  
                    return true;    
                path.remove(path.size()-1);    
            }    
                
            if(root.right!=null) {    
                path.add(root.right);    
                if(getPath(root.right, n, path))   
                    return true;    
                path.remove(path.size()-1);    
            }    
            return false;    
        }  
轉載:http://blog.csdn.net/qq_25827845/article/details/74612786