leetcode二叉树简单题技巧总结

1. 二叉树的先序、中序、后序遍历

使用dfs算法(深度优先)

(1) 先序

List<Integer> list = new ArrayList();
public void preOrder(TreeNode root){
	//向集合中添加数据
	list.add(root.val);
	//递归左子树
	if(root.left!=null)
		preOrder(root.left);
	//递归右子树
	if(root.right!=null)
		preOrder(root.right);
}

(2) 中序

public void inOrder(TreeNode root){
	if(root.left!=null)
	preOrder(root.left);

	list.add(root.val);
	if(root.right!=null)
	preOrder(root.right);
}

(3) 后序

public void postOrder(TreeNode root){
	if(root.left!=null)
	preOrder(root.left);
	if(root.right!=null)
	preOrder(root.right);

	list.add(root.val);
}

2. 二叉树的层次遍历

使用bfs算法(广度优先)+队列

(1) 单List集合存储数据的情况

在这里插入图片描述

	List<Integer> list = new ArrayList();
	public void bfs(TreeNode root){
		//1. 创建队列并添加root
   		Queue<TreeNode> queue = new ArrayDeque();
   		if(root!=null)
   			queue.add(root);
   		//2. 循环队列,退出条件为队列为空
   	 	while(!queue.isEmpty()){
   	 		//3. 获取并移除队列第一个节点
   	 		TreeNode node = queue.poll();
   	 		//4. 获取节点的值
   	 		list.add(node.val);
   	 		//5. 当节点左右子树不为空时,加入队列
   	 		if(node.left!=null)
   	 			queue.add(node.left);
   	 		if(node.right!=null)
   	 			queue.add(node.right);
   	 	}
   }

(2) 复合List集合存储数据的情况

	public void bfs(TreeNode root){
		List<List<Integer>> list = new ArrayList();
        Queue<TreeNode> queue = new ArrayDeque();
		if(root!=null)
			queue.add(root);
		while(!queue.isEmpty()){
			//新建List集合
			List<Integer> level = new ArrayList();
			//获取队列大小
			int size=queue.size();
			//循环获取值
			for(int i=0;i<size;i++){
                //获取并移除队列的首节点
				TreeNode node =queue.poll();
				//将数据存储到level中
				level.add(node.val);
				if(node.left!=null)
					queue.add(node.left);
				if(node.right!=null)
					queue.add(node.right);
			}
			list.add(level);
		}
	}

3. 求二叉树的最近公共祖先

此题首先明白一点:作为两个节点的最近公共祖先,一定是两个节点都在其左子树和右子树上

比如下图的6和2两个节点,最近公共祖先为5,这时6在5的左子树上,2在5的右子树上,虽然3也是祖先节点,但6和2都是存在于3的左子树上,所以3不是最近的
在这里插入图片描述

 public TreeNode find(TreeNode root, TreeNode p, TreeNode q) {
 	//递归的第一部分:最后一层嵌套跳出的条件
 	if(root ==null) return null; //如果递归到root为空,则说明没有公共节点
 	if(root == q||root == p) return root; //1. 找到了p和q,返回该root节点,也就是这里的答案
 	//2. 递归遍历,找左子树和右子树
 	TreeNode findLeft = find(root.left,p,q); 
 	TreeNode findRight = find(root.right,p,q);
	
	//3. 递归的第三部分,执行每层递归函数剩下的代码,这里也就是返回找到的结果,相当于执行每个函数的一行代码 return root;
	//如果左子树和右子树不为空,也就是为q和p,则说明是该节点,返回答案
	if(findLeft!=null&&findRight!=null)
		return root;
	else{
		//如果左子树不为空,则说明是一条直线上的祖先关系,即是一条左子树直线上的p、q节点
		if(findLeft!=null)
			return findLeft;
		//和上述同理
		return findRight;
	}
 }

4. 二叉搜索树相关

(1) 判断一颗二叉树是否是二叉搜索树

class Solution {
    static int num=0;
    boolean boolLeft = true;
    boolean boolRight = true;
    public boolean isValidBST(TreeNode root) {
        return judge(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }

    boolean judge(TreeNode root,long min,long max){
    	//递归的第一部分:1. 跳出递归的条件与时机
    	// 当root为空,也就是递归结束时,判断boolLeft与boolRight是否还都是true;
        if(root==null)
            return boolLeft&&boolRight;
        // 这里是为了判断其祖先节点是否满足搜索二叉树,见最后递归参数传值有说明
        if(root.val>=max||root.val<=min)
            return false;
        if(root.right!=null){
            //如果节点大于右子树的值,返回false
            if(root.val>=root.right.val){
                return false;
            }
            //如果左右子树都不为空,则比较左子树和右子树的值
            if(root.left!=null)
                //如果右子树的值小于左子树,返回false
                if(root.right.val<=root.left.val){
                    return false;
                }
        }
        if(root.left!=null){
            //如果节点的值小于左子树的值,则返回false
            if(root.val<=root.left.val){
                return false;
            }
        }
        // 递归的第二部分:2. 递归函数 接收下一层递归函数返回的boolean值
        //这 里的min和max,用于判断其子树是否比祖先节点的值小或大
        boolLeft = judge(root.left,min,root.val);
        boolRight = judge(root.right,root.val,max);

		//递归的第三部分:3.返回最后的结果
        return boolLeft&&boolRight;
    }
}

(2) 二叉搜索树的知识点

二叉搜索树的中序遍历是从小到大排序的数组

持续更新中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值