劍指Offer(第二版)面試案例:樹中兩個節點的最低公共祖先節點
阿新 • • 發佈:2019-01-25
劍指Offer(第二版)面試案例:樹中兩個節點的最低公共祖先節點
題目:輸入兩個樹節點,求它們的最低公共祖先節點。
反問:這棵樹是不是二叉樹?
面試官:是二叉樹,並且是二叉搜尋樹。
思路:
二叉搜尋樹是經過排序的,位於左子樹的節點都比父節點小,位於右子樹的節點都比父節點大。既然要找最低的公共祖先節點,我們可以從根節點開始進行比較。
若當前節點的值比兩個節點的值都大,那麼最低的祖先節點一定在當前節點的左子樹中,則遍歷當前節點的左子節點;
反之,若當前節點的值比兩個節點的值都小,那麼最低的祖先節點一定在當前節點的右子樹中,則遍歷當前節點的右子節點;
這樣,直到找到一個節點,位於兩個節點值的中間,則找到了最低的公共祖先節點。
/** * 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||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; } }
面試官:如果只是普通的二叉樹呢?
反問:樹的節點中有沒有指向父節點的指標?
面試官:為什麼需要指向父節點的指標?
答:如果存在parent指標,則分別從輸入的p節點和q節點指向root根節點,其實這就是兩個單鏈表。問題轉化為求兩個單鏈表相交的第一個公共節點
面試官:那如果不存在parent指標呢?遞迴的解法如下:
迭代解法: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) 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;
}
該題是網際網路面試中出現頻率賊高的二叉樹題目。必須掌握哦~
如果對你有幫助,記得點贊哦~歡迎大家關注我的部落格,可以進群366533258一起交流學習哦~
本群給大家提供一個學習交流的平臺,內設菜鳥Java管理員一枚、精通演算法的金牌講師一枚、一枚、藍芽BlueTooth管理員一枚、Web前端管理一枚以及C#管理一枚。歡迎大家進來交流技術。