得到bst的公共最近祖先节点

23 篇文章 0 订阅

标题:得到bst的公共最近祖先节点

可以看看这个Java实现二叉搜索树的最近公共祖先节点

bst最近公共祖先节点

  • 方法一:得到两个list,【通过bst的搜索直接得到list保存父节点的集合】,使用一个for循环important
  • 方法二;通过bst的搜索特性,这个递归有点意思,
/**
 * bst最近公共祖先节点
 * 方法一:得到两个list,【通过bst的搜索直接得到list保存父节点的集合】,使用一个for循环important
 * 方法二;通过bst的搜索特性,这个递归有点意思,
 * 
 * @author dell
 *
 */
public class TestCommonNode02 {
	/*题目三
	给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
	7 -》 6ms
	*/
	public TreeNode commonBstNode(TreeNode head, TreeNode p1, TreeNode p2){
		/*
		List<TreeNode> list1 = this.selectFaBstNodeToList(head, p1);  //用两个list,和使用list、set差不多
		Set<TreeNode> set = this.selectFaBstNodeToSet(head, p2);
		
		for(int i = list1.size() - 1; i >= 0; i--){	
				if(set.contains(list1.get(i))){//.val要不要都可以
					return list1.get(i);
				}
		}*/
		
		List<TreeNode> list1 = this.selectFaBstNodeToList(head, p1);  
		List<TreeNode> list2 = this.selectFaBstNodeToList(head, p2);  
		
		//使用两个for循环写的
		/*
		执行用时:7 ms, 在所有 Java 提交中击败了38.56% 的用户
		内存消耗:39.4 MB, 在所有 Java 提交中击败了87.30% 的用户
		for(int i = list1.size() - 1; i >= 0; i--){	
			for(int j = 0; j < list2.size(); j++){
				if(list1.get(i) == list2.get(j)){
					return list1.get(i);
				}
			}
		}
		
		return null;
		*/
		
		//=》使用一层for循环  
		/*
		执行结果:
		通过
		显示详情
		执行用时:6 ms, 在所有 Java 提交中击败了99.93% 的用户
		内存消耗:39.4 MB, 在所有 Java 提交中击败了88.09% 的用户
		*/
		TreeNode node = null;
		for(int i = 0; i < list1.size() && i < list2.size(); i++){
			if(list1.get(i) == list2.get(i)){
				node = list1.get(i);
			}else{
				return node;
			}
		}
		
		return node;
	}
	
	//返回p的父节点--》list
	public List<TreeNode> selectFaBstNodeToList(TreeNode head,TreeNode p){
		List<TreeNode> list = new ArrayList<>();
		if(head == null){
			if(p == null){
				return list;
			}
			throw new RuntimeException("head 为null!!!");
		}
		TreeNode node = head;
		while(node != null){
				list.add(node);
			if(p.val == node.val){
				return list;
			}else if(p.val < node.val){
				node = node.left;
			}else {
				node = node.right;
			}
		}
		
		return list;
		
	}
	//返回p的父节点--》set
	public Set<TreeNode> selectFaBstNodeToSet(TreeNode head,TreeNode p){
		Set<TreeNode> set = new HashSet<>();
		if(head == null){
			if(p == null){
				return set;
			}
			throw new RuntimeException("head 为null!!!");
		}
		TreeNode node = head;
		while(node != null){
				set.add(node);
			if(p.val == node.val){
				return set;
			}else if(p.val < node.val){
				node = node.left;
			}else {
				node = node.right;
			}
		}
		
		return set;
		
	}

	//方法二:
	/*递归,利用bst的搜索快
	1.使p1 < p2
	2.如果p1/p2的value == head.val return head
	3.如果一个小于head,一个大于head,return head
	4.如果两个都小于,调用head.left
	5.如果两个都大于,调用head.right

	执行结果:
	通过
	显示详情
	执行用时:6 ms, 在所有 Java 提交中击败了99.93% 的用户
	内存消耗:39.5 MB, 在所有 Java 提交中击败了72.55% 的用户
	*/
	public TreeNode lowestCommonAncestor02(TreeNode head, TreeNode p1, TreeNode p2){
		//确保p1.val < p2.val
		if(p1.val > p2.val){
			return this.lowestCommonAncestor02(head, p2, p1);
		}

	    if(p1.val == head.val || p2.val == head.val){  //注意可能p1/p2就是head
	        return head;
	    }else if(p1.val < head.val && p2.val > head.val){
			return head;
		}else if(p2.val < head.val){
			return this.lowestCommonAncestor02(head.left, p1, p2);
		}else{
			return this.lowestCommonAncestor02(head.right, p1, p2);
		}	
	}

	//=>
	public TreeNode lowestCommonAncestor021(TreeNode head, TreeNode p1, TreeNode p2){
		if(p1.val < head.val && p2.val < head.val){
			return this.lowestCommonAncestor021(head.left, p1, p2);
		}else if(p1.val > head.val && p2.val > head.val){
			return this.lowestCommonAncestor021(head.right, p1, p2);
		}else{
			return head;
		}
	}

	/*
	方法二的非递归版  思想和上面一样
	执行用时:7 ms, 在所有 Java 提交中击败了38.56% 的用户
	内存消耗:39.1 MB, 在所有 Java 提交中击败了96.86% 的用户
	*/
	public TreeNode lowestCommonAncestor(TreeNode head, TreeNode p1, TreeNode p2){
		//确保p1.val < p2.val
		if(p1.val > p2.val){
			return this.lowestCommonAncestor(head, p2, p1);
		}
		if(head == null){
			return null;
		}
		
		TreeNode node = head;
		while(node != null){
			if(p1.val == node.val || p2.val == node.val){  //注意可能p1/p2就是head
				return node;
			}else if(p1.val < node.val && p2.val > node.val){
				return node;
			}else if(p2.val < node.val){
				node = node.left;
			}else{
				node = node.right;
			}
		}
		
	    return null;	
	}
	
	/**
	 * 初始化一个tree
	 * 类广度遍历
	 * @param a
	 * @return
	 */
	public TreeNode initTree(Integer[] a) {
		if(a == null || a.length == 0) {
			return null;
		}
		
		int t = 0;
		TreeNode p = new TreeNode(a[t]);  //至少有一个元素
		Queue<TreeNode> q = new LinkedList<>();
		q.offer(p);
		
		while(!q.isEmpty()) {
			TreeNode node = q.poll();
			if(t + 1 == a.length) {  //先判断数组中是否还有下一个元素
				return p;
			}else {
				t++;
				if(a[t] == null) {  //若下一个元素为null,则不需要创建新的节点
					node.left = null;
				}else {
					node.left = new TreeNode(a[t]);
					q.offer(node.left);
				}
			}
			if(t + 1 == a.length) {
				return p;
			}else {
				t++;
				if(a[t] != null){  //上面的简写,a[t] == null,不需要再赋值
					node.right = new TreeNode(a[t]);
					q.offer(node.right);
				}
			}
		}
		
		return p;
	}
	
	@Test
	public void test() {
		Integer[] a = new Integer[] {1, 2, 3, 4, 5, 9, 10, null, 6, 7, 8, null, null, null, 11};
		
		TreeNode head = this.initTree(a);
		TreeNode p1 = new TreeNode(9);
		TreeNode p2 = new TreeNode(8);
		
	
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值