剑指 Offer 26. 树的子结构 & 27. 二叉树的镜像 & 28. 对称的二叉树

26题目描述:

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如: 给定的树 A:

     3
    / \
   4   5
  / \
 1   2

给定的树 B:

   4 
  /
 1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

解析:

1.首先如果A或者B为空,直接返回false,因为题目约定空树不是任意一个树的子结构
2.然后去判断几种情况,
(1)A的根节点和B的根节点相同的情况,依次比较它们的子节点
(2)A的根节点和B的根节点不相同的情况,A的左子树和B的根节点进行比较
(3)A的根节点和B的根节点不相同的情况,A的右子树和B的根节点进行比较
3.创建辅助函数
(1)遍历完B,直到为空,说明B的全部节点都和A的子结构匹配上,返回true
(2)A的节点为空,但B的节点不为空,说明不匹配,返回false
(3)A和B都不为空,但数值不同,说明不匹配,返回false
(4)此时,当这个点时匹配的,继续递归去判断左子树和右子树是否分别匹配

Java:

public boolean isSubStructure(TreeNode A, TreeNode B) {
        if(A == null || B == null) {
            return false;
        }
        return isSub(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
    }
    boolean isSub(TreeNode A, TreeNode B) {
        if(B == null) {
            return true;
        }
        if(A == null || A.val != B.val) {
            return false;
        }
        return isSub(A.left, B.left) && isSub(A.right, B.right);
    }

JavaScript:

var isSubStructure = function(A, B) {
    if(A === null || B === null) {
        return false;
    }
    function isSub(A, B) {
        if(B === null) {
            return true;
        }
        if(A === null || A.val !== B.val) {
            return false;
        }
        return isSub(A.left, B.left) && isSub(A.right, B.right);
    }
    return isSub(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
};

27题目描述:

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

例如输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

镜像输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

解析:

1.当节点为空时,直接返回空
2.设置一个临时节点temp,用来存储当前节点的左子树
3.以下有两个操作是交换当前节点的左右子树
当前节点的左子树为节点的右子树,同时递归下去,不停的交互子树中的节点
当前节点的右子树为节点的左子树,同时递归下去,不停的交互子树中的节点
4.最后返回根节点

Java:

public TreeNode mirrorTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        TreeNode ans = new TreeNode(root.val);
        ans.left = mirrorTree(root.right);
        ans.right = mirrorTree(root.left);
        return ans;
    }

JavaScript:

var mirrorTree = function(root) {
    if(root === null) {
        return null;
    }
    let temp = root.left;
    root.left = mirrorTree(root.right);
    root.right = mirrorTree(temp);
    return root;
};

28题目描述:

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

例如,二叉树 [1,2,2,3,4,4,3] 是对称的,则返回true

    1
   / \
  2   2
 / \ / \
3  4 4  3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的,则返回false

    1
   / \
  2   2
   \   \
   3    3

解析:

1.边界情况,如果根节点为空,则返回true
2.递归判断左子树和右子树是否对称
3.创建辅助函数去判断
(1)如果某根子树的左右两子树同时为空,则肯定是对称的,直接返回true
(2)如果根子树的左右两子树有某子树为空,某子树有值,则不对称,返回false
(3)左子树的值与右子树的值不相等,不对称,返回false
(4)递归的对比当前节点的左子树的左子树与右子树的右子树、左子树的右子树与右子树的左子树是否对称

Java:

public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return isSymmetriacalCor(root.left, root.right);
    }
    private boolean isSymmetriacalCor(TreeNode L, TreeNode R) {
        if(L == null && R == null) {
            return true;
        }
        if(L == null || R == null) {
            return false;
        }
        if(L.val != R.val) {
            return false;
        }
        return isSymmetriacalCor(L.left, R.right) && isSymmetriacalCor(L.right, R.left);
    }

JavaScript:

var isSymmetric = function(root) {
    if(root === null) {
        return true;
    }
    return isSymmetriacalCor(root.left, root.right);

    function isSymmetriacalCor(L, R) {
        if(L === null && R === null) {
            return true;
        }
        if(L === null || R === null) {
            return false;
        }
        if(L.val !== R.val) {
            return false;
        }
        return isSymmetriacalCor(L.left, R.right) && isSymmetriacalCor(L.right, R.left);
    }
};
全部评论

相关推荐

求offer的大角牛:不吃香菜
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务