剑指offer 17、18

17、 树的子结构

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

对于Python这道题,有些地方需要仔细考虑的。

先说下算法实现思路:对于两棵二叉树来说,要判断B是不是A的子结构,首先第一步在树A中查找与B根节点的值一样的节点。

通常对于查找树中某一个节点,我们都是采用递归的方法来遍历整棵树。

第二步就是判断树A中以R为根节点的子树是不是和树B具有相同的结构。

这里同样利用到了递归的方法,如果节点R的值和树的根节点不相同,则以R为根节点的子树和树B肯定不具有相同的节点;

如果它们值是相同的,则递归的判断各自的左右节点的值是不是相同。

递归的终止条件是我们达到了树A或者树B的叶节点。

有地方要重点注意,DoesTree1haveTree2()函数中的两个 if 判断语句 不能颠倒顺序 。
因为如果颠倒了顺序,会先判断pRoot1 是否为None, 其实这个时候,pRoot1 的节点已经遍历完成确认相等了,但是这个时候会返回 False,判断错误。

有同学不相信的,可以去试试换个顺序,肯定不能AC。同时这个也是《剑指offer》书上没有写的,希望能引起大家的注意。


```python
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        result = False
        if pRoot1 != None and pRoot2 != None:
            if pRoot1.val == pRoot2.val:
                result = self.DoesTree1haveTree2(pRoot1, pRoot2)
            if not result:
                result = self.HasSubtree(pRoot1.left, pRoot2)
            if not result:
                result = self.HasSubtree(pRoot1.right, pRoot2)
        return result
    # 用于递归判断树的每个节点是否相同
    # 需要注意的地方是: 前两个if语句不可以颠倒顺序
    # 如果颠倒顺序, 会先判断pRoot1是否为None, 其实这个时候pRoot2的结点已经遍历完成确定相等了, 但是返回了False, 判断错误
    def DoesTree1haveTree2(self, pRoot1, pRoot2):
        if pRoot2 == None:
            return True
        if pRoot1 == None:
            return False
        if pRoot1.val != pRoot2.val:
            return False
        return self.DoesTree1haveTree2(pRoot1.left, pRoot2.left) and self.DoesTree1haveTree2(pRoot1.right, pRoot2.right)

另一个比较好的写法:考虑的比较全面
在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        def same(pRoot1, pRoot2):
            if not pRoot2:
                return True
            elif pRoot1 and pRoot2:
                if pRoot1.val == pRoot2.val:
                    return same(pRoot1.left, pRoot2.left) and same(pRoot1.right, pRoot2.right)
                else:
                    return False
            else:
                return False
        if pRoot1 and pRoot2:
         return same(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2)
        else:
            return False

18、二叉树的镜像

操作给定的二叉树,将其变换为源二叉树的镜像。

在这里插入图片描述递归

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root is None:
            return
        tmp = root.right
        root.right = root.left
        root.left = tmp
        self.Mirror(root.left)
        self.Mirror(root.right)
        return root
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页