• 《剑指 Offer》学习记录:题 27:二叉树的镜像


    题 27:二叉树的镜像

    题干

    题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。——《剑指 Offer》P157

    测试用例

    二叉树的类定义如下(python):

    # Definition for a binary tree node.
    class TreeNode:
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    

    例如传入的二叉树结构为:

    则函数返回的二叉树的镜像的结构为:

    分治法

    方法思路

    二叉树的镜像的特点在于,二叉树中的所有结点左右都要对调。这个问题可以用分治的思想来考虑,也就是把大问题分解为 n 个小问题。对于一个结点来说可以分为 2 个子问题,分别是左子树修改为其镜像,右子树修改为其镜像,接着只需要把左右子树调换即可。例如对于刚刚的二叉树,想要把结点 1 变为镜像,可以分解为将结点 2 和结点 3 修改为其镜像:

    结点 2 和结点 3 修改为其镜像后,再交换结点 1 的左右子树。

    题解代码

    class Solution:
        def mirrorTree(self, root: TreeNode) -> TreeNode:
            if root == None:
                return None
            left = root.left
            root.left = self.mirrorTree(root.right)
            root.right = self.mirrorTree(left)
            return root
    

    时空复杂度

    设二叉树共有 n 个结点,算法需要遍历二叉树的所有结点,时间复杂度为 O(n)。
    由于递归需要额外的空间保存状态,所以空间复杂度为 O(n)。

    迭代法

    方法思路

    除了使用分治的思想,也可以把二叉树的镜像过程理解为对二叉树进行层序遍历,然后将每一层的序列颠倒。此时可以使用栈结构实现逆序,因为栈结构具有先进后出的特点,可以将一层的结点顺序颠倒。例如对于刚刚的二叉树,初始状态下只有根结点入栈:

    将栈顶出栈,把结点 1 的左、右节点分别入栈,然后对调结点 1 的左右子树。

    将结点 3 出栈,把结点 3 的左、右节点分别入栈,然后对调结点 3 的左右子树。

    将结点 6 出栈,由于结点 6 是子叶节点,所以不需要进行其他操作。

    将结点 2 出栈,把结点 2 的左、右节点分别入栈,然后对调结点 2 的左右子树。

    将结点 5 出栈,由于结点 5 是子叶节点,所以不需要进行其他操作。将结点 4 出栈,由于结点 4 是子叶节点,所以不需要进行其他操作。最后栈空,表示算法结束,得到了原二叉树的镜像。

    题解代码

    class Solution:
        def mirrorTree(self, root: TreeNode) -> TreeNode:
            if root == None:
                return root
            stack = [root]
            while stack:
                node = stack.pop()
                if node.left != None:
                    stack.append(node.left)
                if node.right != None:
                    stack.append(node.right)
                node.left, node.right = node.right, node.left
            return root
    

    时空复杂度

    设二叉树共有 n 个结点,算法需要遍历二叉树的所有结点,时间复杂度为 O(n)。
    由于需要额外一个栈结构作为辅助,所以空间复杂度为 O(n)。

    参考资料

    《剑指 Offer(第2版)》,何海涛 著,电子工业出版社
    剑指 Offer 27. 二叉树的镜像(递归 / 辅助栈,清晰图解)

  • 相关阅读:
    进程间通讯----消息队列和共享内存方式的实现
    初探 Yii2 的测试模式 index-test.php
    nginx缓存功能的设置
    php五大运行模式CGI,FAST-CGI,CLI,ISAPI,APACHE模式
    workerman如何写mysql连接池
    Varnish 一般是放在 Nginx 前面还是后面的?
    关于PATH_INFO
    Java8 Lambda表达式
    synchronized的一些记录
    类和实例
  • 原文地址:https://www.cnblogs.com/linfangnan/p/14698713.html
Copyright © 2020-2023  润新知