二叉搜索树
题目
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
利用二叉树的特点 其左节点小于根结点小于右节点。利用其有序的特性,进行如下两种方法
- 按照从root出发,查找目标节点的路径,最后返回两路径的最近重复值。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
List<TreeNode> path_p = get_path(root,p);
List<TreeNode> path_q = get_path(root,q);
TreeNode ans = null;
for(int i=0;i<path_p.size() && i< path_q.size();i++){
if(path_p.get(i) == path_q.get(i)){
ans = path_q.get(i);
}else{
break;
}
}
return ans;
}
public List<TreeNode> get_path(TreeNode root,TreeNode target){
List<TreeNode> path = new LinkedList<>();
TreeNode node = root;
while(node != null){
if(node.val != target.val){
path.add(node);
}
if(node.val > target.val){
node = node.left;
}else if(node.val < target.val){
node = node.right;
}else{
break;
}
}
path.add(node);
return path;
}
}
2.按照二叉搜索树的特性,其祖节点 大于等于左边节点,小于等于右边节点的特性。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode ans = root;
while(ans != null){
if(ans.val > p.val && ans.val > q.val){
ans = ans.left;
}else if(ans.val < p.val && ans.val < q.val){
ans = ans.right;
}else{
break;
}
}
return ans;
}
}
二叉树
由于二叉树是无序的,所以不能利用二叉搜索树的性质去解。
方法1:利用map保存节点和其父节点。利用set判断其是否公共父节点,分别从目标值开始向父节点遍历。
class Solution {
Map<Integer,TreeNode> map;
Set<Integer> set;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
map = new HashMap<>();
set = new HashSet<>();
dfs(root);
while(p != null){
set.add(p.val);
p = map.get(p.val);
}
while(q != null){
if(set.contains(q.val)){
return q;
}
q = map.get(q.val);
}
return null;
}
public void dfs(TreeNode root){
if (root.left!=null){
map.put(root.left.val,root);
dfs(root.left);
}
if(root.right != null){
map.put(root.right.val,root);
dfs(root.right);
}
}
}
方法2:利用回溯
class Solution {
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 null;
else if(left != null && right == null) return left;
else if(left == null && right != null) return right;
else return root;
}
}