LeetCode二叉树习题汇总

1. Num102——二叉树的层序遍历

1.1 问题描述

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述

1.2 解析

package bin_tree.leetcode;

import java.util.*;

public class Num102_LevelOrder {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret=new ArrayList<>();
        if (root==null){
            return ret;
        }
        // 借助队列实现二叉树的层序遍历过程
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            // 使用temp数组保存当前层的元素
            List<Integer> curlist=new ArrayList<>();
            //将当前层的元素取出存入curlist
            int size=queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode cur=queue.poll();
                curlist.add(cur.val);
                if (cur.left!=null){
                    queue.offer(root.left);
                }
                if (cur.right!=null){
                    queue.offer(root.right);
                }
            }
            ret.add(curlist);
        }
        return ret;
    }

      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;
          }
      }
}

2 剑指 Offer 55 - II. 平衡二叉树

2.1 题目描述

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
在这里插入图片描述

2.2 解析

思路:计算二叉树左右子树高度,再判断左右子树高度相差是否超过1

package bin_tree.leetcode;

/**
 * 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。
 * 如果某二叉树中任意节点的左右子树的深度相差不超过1,
 * 那么它就是一棵平衡二叉树
 */
// 思路:利用递归求左子树的深度leftmax和右子树的深度rightmax
    // 当leftmax-rightmax的绝对值>1 不平衡
public class Offer55_isBalanced {
    public boolean isBalanced(TreeNode root) {
        if (root==null){
            return true;
        }
        // 根节点左子树高度
        int leftmax=getheight(root.left);
        // 根节点右子树高度
        int righttmax=getheight(root.right);
        if (Math.abs(leftmax-righttmax)>1){
            return false;
        }else {
            return true;
        }
    }
    // 计算二叉树深度
    public static int getheight(TreeNode root){
        if (root==null){
            return 0;
        }
        int leftheight=getheight(root.left);
        int rightheight=getheight(root.right);
        return Math.max(leftheight,rightheight)+1;
    }
     public class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
     }
}

但上面的思路只是求了根节点的左右子树高度差,对下面这种情况就会出错,注意平衡二叉树需要每个节点都满足高度差不超过1的条件
在这里插入图片描述
正确代码

package bin_tree.leetcode;

/**
 * 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。
 * 如果某二叉树中任意节点的左右子树的深度相差不超过1,
 * 那么它就是一棵平衡二叉树
 */
public class Offer55_isBalanced {
    public boolean isBalanced(TreeNode root) {
        if (root==null){
            return true;
        }
        int leftmax=getheight(root.left);
        int righttmax=getheight(root.right);
        // 判断root的左子树和右子树的高度差以外,还要求每个结点的高度差是否满足条件
        if ((Math.abs(leftmax-righttmax)<=1) && isBalanced(root.left) && isBalanced(root.right)){
            return true;
        }else {
            return false;
        }
    }
    // 计算二叉树深度
    public static int getheight(TreeNode root){
        if (root==null){
            return 0;
        }
        int leftheight=getheight(root.left);
        int rightheight=getheight(root.right);
        return Math.max(leftheight,rightheight)+1;
    }
     public class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
     }
}

3.剑指 Offer 28. 对称的二叉树

3.1 题目描述

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
在这里插入图片描述

3.2 解析

思路:二叉树的前序遍历 根左右
对称前序遍历 根右左
若二叉树为对称二叉树则二叉树的前序遍历结果和对称前序遍历 结果相同
细节:一定要注意保存空结点(若不存储空结点,则结构有可能不同)

package bin_tree.leetcode;

import bin_tree.MyBinTree;

import java.util.ArrayList;
import java.util.List;

/**
 * 思路:二叉树的前序遍历 根左右
 *        对称前序遍历  根右左
 * 若二叉树为对称二叉树则二叉树的前序遍历结果和对称前序遍历 结果相同
 * 细节:一定要注意保存空结点
 */
public class Num101_isSymmetric {
    // 创建两个列表保存二叉树的前序、对称前序遍历结果
    List<Integer> ret=new ArrayList<Integer>();
    List<Integer> ret1=new ArrayList<Integer>();
    public boolean isSymmetric(TreeNode root) {
        // 若根节点为空,直接返回false
        if(root==null){
            return false;
        }
        // ret保存二叉树前序遍历节点值
        ret=preorderTraversal(root);
        // ret1保存二叉树前序兑成遍历节点值
        ret1=preorderTraversal1(root);
        // 判断两种遍历结果是否相同
        return ret.equals(ret1);
    }
    public List<Integer> preorderTraversal(TreeNode root){
        if (root==null){
            ret.add(null);
            return ret;
        }
        ret.add(root.val);
        preorderTraversal(root.left);
        preorderTraversal(root.right);
        return ret;
    }
    public List<Integer> preorderTraversal1(TreeNode root){
        if (root==null){
            ret1.add(null);
            return ret1;
        }
        ret1.add(root.val);
        preorderTraversal1(root.right);
        preorderTraversal1(root.left);
        return ret1;
    }
    /**
     * 创建一个二叉树,返回根节点
     */
    public static TreeNode build() {
        // 创建8个节点
        TreeNode nodeA = new TreeNode('1');
        TreeNode nodeB = new TreeNode('2');
        TreeNode nodeC = new TreeNode('2');
        TreeNode nodeD = new TreeNode('3');
        TreeNode nodeE = new TreeNode('4');
        TreeNode nodeF = new TreeNode('4');
        TreeNode nodeG = new TreeNode('3');
        // 将这8个节点进行连接
        nodeA.left = nodeB;
        nodeA.right = nodeC;
        nodeB.left = nodeD;
        nodeB.right = nodeE;
        nodeC.left = nodeF;
        nodeC.right = nodeG;
        return nodeA;
    }
     public static 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;
         }
     }
    public static void main(String[] args) {
       TreeNode root=build();
        Num101_isSymmetric a=new Num101_isSymmetric();
        System.out.println(a.isSymmetric(root));
    }
}

4.Num100—— 相同的树

4.1 题目描述

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
在这里插入图片描述

3.2 解析

若两个二叉树相同,则用同样的遍历方式遍历的结果是相同的

/**
 * 思路:二叉树的前序遍历 根左右
 * 若二叉树为相同的二叉树则二叉树的前序遍历结果结果相同
 * 细节:一定要注意保存空结点
 */
public class Num100_isSameTree{
    // 创建两个列表保存二叉树的前序遍历结果
    List<Integer> ret=new ArrayList<Integer>();
    List<Integer> ret1=new ArrayList<Integer>();
    public boolean isSameTree(TreeNode p, TreeNode q)  {
        // 若根节点为空,直接返回false
        if(p==null && q!=null){
            return false;
        } if(p!=null && q==null){
            return false;
        }
        // ret保存P二叉树前序遍历节点值
        ret=preorderTraversal(p,ret);
        // ret1保存q二叉树前序遍历节点值
        ret1=preorderTraversal(q,ret1);
        // 判断两种遍历结果是否相同
        return ret.equals(ret1);
    }
    public List<Integer> preorderTraversal(TreeNode p,List<Integer> ret){
        if (p==null){
            ret.add(null);
            return ret;
        }
        ret.add(p.val);
        preorderTraversal(p.left,ret);
        preorderTraversal(p.right,ret);
        return ret;
    }
    /**
     * 创建一个二叉树,返回根节点
     */
    public static TreeNode build() {
        TreeNode nodeA = new TreeNode(1);
        TreeNode nodeB = new TreeNode(2);
        TreeNode nodeC = new TreeNode(1);
        nodeA.left = nodeB;
        nodeA.right = nodeC;
        return nodeA;
    }
    public static TreeNode build1() {
        TreeNode nodeA = new TreeNode(1);
        TreeNode nodeB = new TreeNode(1);
        TreeNode nodeC = new TreeNode(2);
        nodeA.left = nodeB;
        nodeA.right = nodeC;
        return nodeA;
    }
    public static 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;
        }
    }
    public static void main(String[] args) {
        TreeNode p=build();
        TreeNode q=build1();
        Num100_isSameTree a=new Num100_isSameTree();
        System.out.println(a.isSameTree(p,q));
    }
}

5 剑指 Offer 26. 树的子结构

5.1 题目描述

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
在这里插入图片描述

5.2 解析

package bin_tree.leetcode;

import bin_tree.MyBinTree;

/**
 * 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
 * B是A的子结构, 即 A中有出现和B相同的结构和节点值。
 */
public class offer26_isSubStructure {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        // 若两个根节点其中一个为空 则返回false
        if (A==null || B==null){
            return false;
        }
        return isrootsub(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B);


    }
    public static boolean isrootsub(TreeNode root,TreeNode sub){
        // 判断sub是否为null,若sub为空 则匹配成功
        if (sub==null){
            return true;
        }
        // 若sub子结构没有匹配完,但root已经走完
        if(root==null){
            return false;
        }
        // 若两个结点的值不同,则返回false
        if (root.val!=sub.val){
            return false;
        }
        // 递归判断其余结点
        return isrootsub(root.left,sub.left)&& isrootsub(root.right,sub.right);
    }
    public static TreeNode build(){
        TreeNode nodeA=new TreeNode(4);
        TreeNode nodeB=new TreeNode(2);
        TreeNode nodeC=new TreeNode(3);
        TreeNode nodeD=new TreeNode(4);
        TreeNode nodeE=new TreeNode(5);
        TreeNode nodeF=new TreeNode(6);
        TreeNode nodeG=new TreeNode(7);
        TreeNode nodeH=new TreeNode(8);
        TreeNode nodeI=new TreeNode(9);
        nodeA.left=nodeB;
        nodeA.right=nodeC;
        nodeB.left=nodeD;
        nodeB.right=nodeE;
        nodeD.left=nodeH;
        nodeD.right=nodeI;
        nodeC.left=nodeF;
        nodeC.right=nodeG;
        return nodeA;
    }
    public static TreeNode build1(){
        TreeNode nodeA=new TreeNode(4);
        TreeNode nodeB=new TreeNode(8);
        TreeNode nodeC=new TreeNode(9);
        nodeA.left=nodeB;
        nodeA.right=nodeC;
        return nodeA;
    }
     public static class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
     }

    public static void main(String[] args) {
        TreeNode A=build();
        TreeNode B=build1();
        offer26_isSubStructure a=new offer26_isSubStructure();
        System.out.println(a.isSubStructure(A,B));
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值