【LeetCode】树的子结构&&二叉树的镜像&&对称的二叉树

17.树的子结构

题目:

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

题解:

recur函数,递归判断两个子树是否相等

  • 递归结束的条件
    • B为null,因为null为任意一个树的子结构,返回true;
    • 如果A为null则说明B比A多,返回false;
    • 如果A和B的val不相等,返回false。
  • 如果A和B未达到结束的条件,则递归的调用recur函数分别判断左右子树是否相等。

isSubStructure函数,判断是否是子树

  • 如果A或B为null,则返回false;
  • 调用recur函数判断A和B是否相等,递归调用isSubStructure函数判断B是否为A.left的子树,B是否为A.right的子树。
public boolean isSubStructure(TreeNode A, TreeNode B) {
        if (A == null || B == null) return false;
        return recur(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B);
    }
    boolean recur(TreeNode A, TreeNode B) {
        if (B == null) return true;
        if (A == null || A.val != B.val) return false;
        return recur(A.left,B.left) && recur(A.right,B.right);
    }

18.二叉树的镜像

题目:

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

题解:

swap函数递归交换每个节点的左右节点

  • 递归结束的条件
    • A和B均为null,说明root为叶子节点,不需要继续向下交换左右节点,递归结束;
  • 如果未达到递归结束的条件
    • 利用中间节点temp实现root左右节点的交换;
    • 如果左子树不为null,则递归交换其左右节点;
    • 如果右子树不为null,则递归交换其左右节点。
   public TreeNode mirrorTree(TreeNode root) {
        if (root == null) return null;
        TreeNode res = root;
        swap(root,root.left,root.right);
        return res;
    }
    void swap(TreeNode root,TreeNode A, TreeNode B){
        if (A == null && B == null) return;
        TreeNode temp;temp = A;
        root.left = root.right;
        root.right = temp;
        if (A != null) swap(A,A.left,A.right);
        if (B != null) swap(B,B.left,B.right);
    }

19.对称的二叉树

题目:

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

题解一:
  • 使用mirrorTree函数获得二叉树的镜像;
  • 使用isEqual函数判断镜像和原二叉树是否相同;
  • 由于mirrorTree函数的具体实现是在原二叉树的基础上交换左右节点,因此需要copy函数获得二叉树的副本

mirrorTree 函数

  • 详情见 [18.二叉树的镜像]

isEqual 函数

  • 递归结束的条件
    • A为空&&B不为空 或者 A不为空&&B为空,返回false;
    • 二者均为null,返回true;
    • 若二者均不为null,且A.val != B.val ,返回false。
  • 未满足递归结束的条件
    • 即二者均不为null,且A.val == B.val;
    • 此时递归的调用isEqual函数,判断A的左子树和B的左子树是否相同、A的右子树和B的右子树是否相同

copy 函数

  • 应用深度拷贝的思想;
  • 首先通过queue遍历二叉树的所有节点,并创建与其相对应的节点,将二者存入map中;
  • 二次遍历二叉树,设置新节点的左右节点。
    public TreeNode mirrorTree(TreeNode root) {
        if (root == null) return null;
        TreeNode res = root;
        swap(root,root.left,root.right);
        return res;
    }
    void swap(TreeNode root,TreeNode A, TreeNode B){
        if (A == null && B == null) return;
        TreeNode temp;temp = A;
        root.left = root.right;
        root.right = temp;
        if (A != null) swap(A,A.left,A.right);
        if (B != null) swap(B,B.left,B.right);
    }

    public boolean isSymmetric(TreeNode root) {
        TreeNode tempRoot = copy(root);
        TreeNode mirror = mirrorTree(root);
        return isEqual(tempRoot,mirror);
    }

    public boolean isEqual(TreeNode A,TreeNode B) {
        if ((A == null && B != null) || (A != null && B == null )) return false;
        if (A == null && B == null) return true;
        if (A.val != B.val) return false;
        return isEqual(A.left,B.left) && isEqual(A.right,B.right);
    }
    TreeNode copy(TreeNode root){
        if (root == null) return null;
        Queue<TreeNode> queue = new LinkedList<TreeNode>(){{add(root);}};
        Map<TreeNode,TreeNode> map = new HashMap<>();
        while (!queue.isEmpty()){
            TreeNode remove = queue.remove();
            TreeNode treeNode = new TreeNode(remove.val);
            map.put(remove,treeNode);
            if (remove.left != null) queue.add(remove.left);
            if (remove.right != null) queue.add(remove.right);
        }
        queue.add(root);
        while (!queue.isEmpty()){
            TreeNode poll = queue.poll();
            map.get(poll).left = map.get(poll.left);
            map.get(poll).right = map.get(poll.right);
            if (poll.left != null) queue.add(poll.left);
            if (poll.right != null) queue.add(poll.right);
        }
        return map.get(root);
    }
题解二:
  • 若节点L和节点R对称,则应该满足L.left和R.right对称,L.right和R.left对称;

isSymmetric 函数

  • 如果root为null,返回true;
  • 调用recur函数,判断root的左右子树是否对称。

recur 函数

  • 递归结束的条件
    • L和R均为null,则二者必然对称,返回true;
    • 若L为null(此时R不为null)、R为null(此时L为null)、L和R的val不同(此时L和R均不为null)时,二者不对称,返回false;
  • 未满足递归结束的条件
    • 即L和R均不为null,且L.val == R.val;
    • 此时递归调用recur函数判断L.left和R.right是否对称,L.right和R.left是否对称。
  public boolean isSymmetric(TreeNode root) {
        if (root == null) return true;
        return recur(root.left,root.right);
        }
        boolean recur(TreeNode L, TreeNode R) {
        if(L == null && R == null) return true;
        if(L == null || R == null || L.val != R.val) return false;
        return recur(L.left, R.right) && recur(L.right, R.left);
        }

在我们这个星球上,每天都要发生许多变化,有人倒霉了;有人走运了;有人在创造历史,历史也在成全或抛弃某些人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值