day6-7算法:树、二叉树、二叉搜索树

1. 题目

  1. 给定一个二叉树,判断其是否是一个有效的二叉搜索树:https://leetcode-cn.com/problems/validate-binary-search-tree/
  2. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

2. 基本知识

树、二叉树、二叉搜索树

2.1 树

由N个点构成的一种数据结构,有一个根节点和多层的子节点组成,连接的顺序都是从根节点指向孩子节点。每一个子节点都只有一个前驱节点,但一个父节点可能有多个孩子节点。

一棵普通的树

2.2 二叉树

二叉树是树的一种,它的特点是每一个节点最多只有两个子节点。

这是一个满二叉树

2.3 二叉搜索树

它是二叉树的一种,又叫有序二叉树。它是指一棵空树或者有以下性质的二叉树。增删查的时机复杂度为O(logn)

  • 左子树上所有节点的值均小于它的根节点的值
  • 右子树上所有的节点的值均大于它的根节点的值
  • 左右子树也分别为小二叉搜索树

二叉搜索树

3. 算法题解题

3.1 给定一个二叉树,判断其是否是一个有效的二叉搜索树

假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。把每个节点的next指向它的前一个节点即可。

解法1:中序遍历法
左节点-父节点-右节点,这个遍历顺序,则判断前一个节点的值比后一个节点的值小即可。
时间复杂度为O(n),空间复杂度也为O(n)

public class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;

	TreeNode(int x) {
		val = x;
	}
}


public boolean isValidBST(TreeNode root) {
	
	Stack<TreeNode> stack = new Stack<TreeNode>();
	
	if (root == null) {
		return true;
	}
	
	double inorder = -Double.MAX_VALUE;
	
	while (!stack.isEmpty() || root != null) {
		while(root != null){
			stack.push(root);
			root = root.left;
		}
		
		root = stack.pop();
		
		if (root.val < inorder) {
			return false;
		}
		inorder = root.val;
		root = root.right;
	}
	return false;
}

解法2: 递归
分别递归左右子树,一直递归找到左子树的最大值,右子树的最小值,然后把返回的值进行比较,左节点最大值小于根节点,小于右节点最小值。

public boolean isValidBST(TreeNode root) {

	return validHelper(root ,null, null);
}

public boolean validHelper(TreeNode root, Integer min, Integer max){
	
	
	if (root == null) {
		return true;
	}
	
	Integer tempVal = root.val;
	
	// 当前值和最小值比较
	if (min != null &&  tempVal <= min) return false;
	
	// 当前值和最大值比较
	if (max != null && tempVal >= max) return false;
	
	
	//递归循环
	//左子树,最大值是当前节点值
	if (!validHelper(root.left, min, tempVal)) return false;
	
	//右子树,最小值是当前节点值
	if(!validHelper(root.right, tempVal, max)) return false;
	
	return true;
	
}

3.2 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

tips:自己也可以是自己的祖先节点

解法1: 递归法

从根节点开始遍历,如果找到其中一个节点,则 temp 标记为1,如果找到其中一个则认为该分支找到了。继续遍历另一个分支,直到left、right、temp其中两个为1时,则认为找到了公共祖先。

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    recurseTree(root, p, q);
    
    return result;
}

TreeNode result;

private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
	
	if (currentNode == null) {
		return false;
	}
	
	int left = recurseTree(currentNode.left, p, q) ? 1 : 0;
	
	int right = recurseTree(currentNode.right, p, q) ? 1 : 0;
	
	int temp= 0; 
	if (currentNode == p || currentNode == q) {
		temp = 1;
	}
	
	if (temp + left + right == 2) {
		result = currentNode;
	}
	
	if (temp + left + right > 0) {
		return true;
	}
	
	return false;
}

4. Tips

一个可以免费上传图片,并分享链接的网站

https://sm.ms/
点击,并上传照片。
然后,分享链接即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值