代码随想录算法训练营第十五天|102. 层序遍历、 226.翻转二叉树、101. 对称二叉树

这篇博客主要探讨了LeetCode中与二叉树层次遍历相关的算法问题,包括102题的层次遍历、116题的填充节点指针、111题的最小深度以及226题的树的翻转。作者通过实例解析了层次遍历的基本思路,如使用队列进行广度优先搜索,并详细介绍了如何在不同题目中应用和变形这些基本方法。此外,还讨论了前序遍历和后序遍历在解决特定问题时的适用性。
摘要由CSDN通过智能技术生成

目录

Leetcode - 102 

Leetcode - 116

Leetcode - 111

Leetcode - 226

Leetcode - 101


Leetcode - 102 

需要和深度优先遍历区分的事,深度优先遍历会用到,但是广度优先遍历会用到队列 ,根节点入队后,出队,记录节点值,然后将左右子节点(若存在) 依次入队,这样反复循环直到队列为空即可。 但是102这题需要将每一层的节点区分出来,这里用的方法是记录当前队列的长度L,然后在队列做出队加子节点入队操作时,仅仅出队L次,然后单独记录,然后再重新记录队列长度,此时队列长度就是下一层的节点数目。

def levelOrder(root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        
        queue = deque()
        queue.append(root)
        res = []
        while queue:
            layer_length = len(queue)
            temp = [0] *layer_length

            for i in range(layer_length):
                elem = queue.popleft()
                temp[i] = elem.val
                if elem.left:
                    queue.append(elem.left)
                if elem.right:
                    queue.append(elem.right)

            res.append(temp)

        return res

还有类似的十题:

        

  • 102.二叉树的层序遍历
  • 107.二叉树的层次遍历II
  • 199.二叉树的右视图
  • 637.二叉树的层平均值
  • 429.N叉树的层序遍历
  • 515.在每个树行中找最大值
  • 116.填充每个节点的下一个右侧节点指针
  • 117.填充每个节点的下一个右侧节点指针II
  • 104.二叉树的最大深度
  • 111.二叉树的最小深度

这里需要单独拧出来说的是116 111

Leetcode - 116

这里需要关注的是,如何将一层的节点中,节点于其右边的节点产生联系,最后一个节点是否需要处理?

首先 每出队一个元素,此时队首元素就是与其相邻的元素,让出队的这个元素指向队首元素即可,到出队最后一个元素后直接break即可,因为其next指针域默认为None

且最后返回的是根节点 这里不要错了

def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        if not root:
            return root

        res =[]
        queue = deque()
        queue.append(root)
        while queue:
            length = len(queue)
            for i in range(length):
                elem = queue.popleft()
                if elem.left:
                    queue.append(elem.left)
                if elem.right:
                    queue.append(elem.right)
                if i == length -1:
                    break
                elem.next = queue[0]
        return root

Leetcode - 111

这题首先要找到第一个叶子节点,即左右子节点均为空,此时停止遍历,判断res的长度即为此时叶子节点所在的深度

def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        queue = deque()
        res = []
        queue.append(root)
        while queue:
            length = len(queue)
            temp = [0] * length
            for i in range(length):
                elem = queue.popleft()
                temp.append(elem.val)

                if not elem.left and not elem.right:
                    res.append(temp)
                    return len(res)

                if elem.left:queue.append(elem.left)
                if elem.right:queue.append(elem.right)
            res.append(temp)

Leetcode - 226

这题一开始我用的是层次遍历去做的,每每从队列pop出一个节点的时候,只要其左右节点存在一个,就进行互换。

def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return root

        queue = deque()
        queue.append(root)

        while queue:
            length = len(queue)
            
            for i in range(length):
                t = queue.popleft()
                if t.left or t.right:
                    t.left,t.right = t.right,t.left

                if t.left: queue.append(t.left)
                if t.right: queue.append(t.right)
        return root

这种方法其实比卡哥说的前序遍历后序遍历效率都要高

卡哥的方法就是,在前序遍历或者后序遍历的“中”操作的地方进行左右节点互换。

def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return root

        def swap(node):
            if node == None:
                return 
            
            node.left,node.right = node.right,node.left
            swap(node.left)
            swap(node.right)

        swap(root)


        return root

为啥不能中序,因为中序的话 左中右,先处理左边,然后互换,此时的右边就是原来的左右,此时再处理右边就等于又处理了一遍原来的左边,原来的右边其实没有处理的,若要写成中序,“右”操作的时候应该还是要处理左边才对

def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return root

        def swap(node):
            if node == None:
                return 
            
            
            swap(node.left)
            node.left,node.right = node.right,node.left
            swap(node.left)

        swap(root)


        return root

Leetcode - 101

这题要用的是后序遍历,因为只有对左边右边都处理完了之后才能返回结果

这里比较的是左右两侧,外侧和内侧都相同才能算对称,比如左边的左子树,右边的右子树相同,算外侧相同,左边的右子树,右边的左子树相同,算内侧相同。递归的参数,就是左右两子节点。终止条件?若左为空右不为空、右为空左不为空,左右不为空但不相等返回False,左右同时为空返回True,只有当左右均不为空,且值相同,才能继续下面的循环

def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return False

        def compare(left,right):
            if left ==None and right != None:
                return False
            elif left != None and right == None:
                return False
            elif left == None and right == None:
                return True
            elif left.val != right.val:
                return False
          

            outer = compare(left.left,right.right)
            inner = compare(left.right,right.left)
            return outer and inner

        return compare(root.left,root.right)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值