6.4翻转二叉树(LC226—送分题,前序遍历)

算法:

第一想法是用昨天的层序遍历,把每一层level用切片反转。但是这样时间复杂度很高。

其实只要在遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了

注意:是指针进行交换,交换的是左右孩子,然后里面的值再交换

首先使用递归法,代码简单:

调试过程:

原因:root没有迭代,一直都是有值的根节点。有递归了,其实不用while循环了。

正确代码:

复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        #root是每一个节点变量,不一定是根节点
        if root == None:
            return None
        else:
            #交换左右孩子指针(V)
            root.left, root.right = root.right, root.left
            #L,每个子树下面的节点进一步进行左右交换
            if root.left:
                root.left = self.invertTree(root.left)
            #R,每个子树下面的节点进一步进行左右交换
            if root.right:
                root.right = self.invertTree(root.right)
        return root

时间空间复杂度:

`invertTree`函数的时间复杂度是O(n),其中n是二叉树中的节点数。这是因为我们对每个节点进行一次访问,并且对每个节点执行固定量的工作。

`invertTree`函数的空间复杂度是O(h),其中h是二叉树的高度。这是因为函数使用递归,递归的最大深度等于树的高度。在最坏的情况下,即树完全不平衡且类似于链表的情况下,树的高度等于节点数,导致空间复杂度为O(n)。然而,在平衡的二叉树中,高度通常是log(n),导致空间复杂度为O(log(n))。

面试官看你顺畅的写出了递归,一般会进一步考察能不能写出相应的迭代

我觉得迭代法就是要加循环:

使用迭代的方式来翻转二叉树。我们从根节点开始,将根节点入栈。然后,进入循环,直到栈为空。在循环中,我们从栈中弹出一个节点,并交换其左右子节点的指针。如果存在左子节点,则将其入栈,如果存在右子节点,则将其入栈。

**`stack`**用于迭代地翻转二叉树。它起到了存储待处理节点的作用。

使用栈的迭代方法相比于递归方法,可以减少递归调用的开销,同时也可以避免递归的最大深度限制。

递归的最大深度限制是什么?

递归的最大深度限制是指递归调用的层数上限。每次进行递归调用时,系统会在内存中为该函数分配一段栈空间,用于保存函数的局部变量、参数和返回地址等信息。当递归的层数过多时,栈空间会被耗尽,导致栈溢出错误。

不同的编程语言和操作系统对递归的最大深度限制可能有所不同。在Python中,默认的最大递归深度是1000层, 超过这个限制将引发"RecursionError"异常。可以使用**`sys.setrecursionlimit()`**函数来修改Python的递归深度限制,但是需要注意修改深度限制可能会导致栈溢出错误。

**为了避免递归的最大深度限制,可以使用迭代的方法来替代递归,**或者使用尾递归优化等技术来减少递归调用的层数。

正确代码:

复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        #root是根节点
        if root == None:
            return None
        else:
            stack = [root]
            #交换左右孩子指针(V)
            while stack:
                #将node定义为每个节点
                node = stack.pop()
                #交换
                node.left, node.right = node.right, node.left
                #L,将node.left存入stack,这样循环时pop出来,进行子节点的交换
                if node.left:
                    stack.append(node.left)                   
                #R,每个子树下面的节点进一步进行左右交换
                if node.right:
                    stack.append(node.right)  
        return root

时间空间复杂度:

时间复杂度:

  • 遍历每个节点并交换其左右子节点的指针需要O(n)的时间,其中n是二叉树中的节点数。

空间复杂度:

  • 使用了一个栈来存储待处理节点,最坏情况下,栈的大小与二叉树的高度成正比,即O(h),其中h是二叉树的高度。
  • 在最坏情况下,当二叉树是一个单链表时,树的高度等于节点数,因此空间复杂度为O(n)。
  • 在平衡的二叉树中,树的高度通常是log(n),因此空间复杂度为O(log(n))。

综上所述,该解决方案的时间复杂度为O(n),空间复杂度为O(h)或O(n)。

相关推荐
BK贝壳3 小时前
bool-hybrid-array 落盘我只认 .bha:用 Create_BHA / Ask_BHA 做布尔数组序列化
数据结构·python·numpy·1024程序员节
企业数字化笔记6 小时前
视频人体姿态怎么做三维可视化?2D关键点、深度局限与技术选型
人工智能·算法·音视频
?abc!6 小时前
(数组)581. 最短无序连续子数组
数据结构·算法·leetcode
小郎君6589 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧9 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
Shimeri9 小时前
越卷越像:我用遗传算法做了个"内卷"实验
算法·three.js·数据可视化·遗传算法·进化算法
Evand J10 小时前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波
guo_wen_qiang10 小时前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖10 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
CCblandy10 小时前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化