秋招力扣Hot100刷题总结——二叉树

二叉树相关的题目基本上都会使用递归,因此做二叉树的题目时首先使用递归,明确递归结束的条件。

1.二叉树的层序遍历 题目链接

  • 题目要求:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
    在这里插入图片描述
  • 代码及思路
    • 使用队列存储每一层的节点,左边节点先入队,右边节点后入队
    • 代码
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        if(root==null)return res;
        Queue<TreeNode> cache=new LinkedList<>();
        cache.offer(root);
        while(!cache.isEmpty()){
            int l=cache.size();
            List<Integer> temp=new ArrayList<>();
            for(int i=0;i<l;i++){
                TreeNode nd=cache.poll();
                temp.add(nd.val);
                if(nd.left!=null)cache.offer(nd.left);
                if(nd.right!=null)cache.offer(nd.right);
            }
            res.add(temp);
        }
        return res;
    }
}

2. 二叉树的最近公共祖先(字节客户端一面) 题目链接

  • 题目要求:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
    在这里插入图片描述
  • 代码及思路
    • 如果一个节点是 p 和 q 的祖先,那么 p 和 q 必须分别在这个节点的左右子树中,或者其中一个就是这个节点本身
    • 从根节点开始递归:如果当前节点是 null,直接返回 null,表示没有找到 p 或 q;如果当前节点是 p 或 q,那么直接返回当前节点;递归地在左子树中寻找 p 和 q;递归地在右子树中寻找 p 和 q
    • 合并递归条件,若左右子树都不为空则返回根节点;若都为空则返回空;若其中一个不为空,则返回不为空的
    • 代码
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==p||root==q)return root;
        if(root==null)return null;
        TreeNode l=lowestCommonAncestor(root.left,p,q);
        TreeNode r=lowestCommonAncestor(root.right,p,q);
        if(l!=null&&r!=null)return root;
        if(l==null&&r!=null)return r;
        if(l!=null&&r==null)return l;
        if(l==null&&r==null)return l;
        return null;
    }
}

3. 合并二叉树 题目链接

  • 题目要求:给你两棵二叉树: root1 和 root2 。
    想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
    返回合并后的二叉树。
    注意: 合并过程必须从两个树的根节点开始。
    在这里插入图片描述
  • 代码及思路
    • 本题使用递归,递归结束的条件是两棵树当前节点中有一个为空或者两个都为空
    • 每次递归的处理是将两棵树中对应的节点合并,然后递归合并一对左节点、一对右节点,同时将该节点的左右节点更新为合并后的左右节点
    • 代码
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1==null&&root2==null)return null;
        if(root1==null||root2==null)return root1==null?root2:root1;
        TreeNode newroot=new TreeNode(root1.val+root2.val);
        TreeNode newleft = mergeTrees(root1.left,root2.left);
        TreeNode newright = mergeTrees(root1.right,root2.right);
        newroot.left=newleft;
        newroot.right=newright;
        return newroot;
    }
}

4. 从前序与中序遍历序列构造二叉树 题目链接

  • 题目描述:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
    在这里插入图片描述
  • 代码及思路
    • 注意重构二叉树必须使用到中序遍历和前序后序其中一个的组合
    • 同样使用递归解决,每一次从前序遍历中找出根节点,然后根据根节点在中序遍历中的位置对数组进行拆分,分别构建左右子树
    • 拆分时可以使用一个hash来存储中序遍历中值和下标的对应关系
    • 代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer,Integer> cache=new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for(int i=0;i<inorder.length;i++){
            cache.put(inorder[i],i);
        }
        return build(preorder,0,preorder.length,inorder,0,inorder.length);
    }
    private TreeNode build(int[] preorder,int prebegin,int preend,int[] inorder,int inbegin,int inend){
        if(prebegin>=preend)return null;
        int index=cache.get(preorder[prebegin]);
        int nodeNum=index-inbegin;
        TreeNode root=new TreeNode(preorder[prebegin]);
        root.left=build(preorder,prebegin+1,prebegin+nodeNum+1,inorder,inbegin,inbegin+nodeNum);
        root.right=build(preorder,prebegin+1+nodeNum,preend,inorder,inbegin+nodeNum+1,inend);
        return root;
    }
}

5. 翻转二叉树 题目链接

  • 题目要求:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
    在这里插入图片描述
  • 代码及思路
    • 首先将根节点的左右子树交换,然后递归交换左右子树的孩子节点
    • 代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root==null)return root;
        if(root.left==null&&root.right==null)return root;
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

6.二叉树展开为链表 题目链接

  • 题目要求:给你二叉树的根结点 root ,请你将它展开为一个单链表:
    展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
    展开后的单链表应该与二叉树 先序遍历 顺序相同。
    在这里插入图片描述
  • 代码及思路
    • 先递归分别展开左右子树,然后保留原右子树,并将右子树指向原左子树,原左子树指向null
    • 遍历root节点的右子树,知道最后一个节点,将最后一个节点的右指针指向原右子树
    • 代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        if(root==null)return;
        if(root.left==null&&root.right==null)return;
        flatten(root.left);
        flatten(root.right);
        TreeNode temp=root.right;
        root.right=root.left;
        root.left=null;
        while(root.right!=null){
            root=root.right;
        }
        root.right=temp;
    }
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值