Day14 二叉树part2

首先复习下昨天的知识点,刷三道模板题增加点信心~

LC 637. 二叉树的层平均值

class Solution:
    def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        res , queue = [] , collections.deque()
        queue.append(root)
        while queue:
            temp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                temp.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(sum(temp) / len(temp))
        return res

LC 515. 在每个树行中找最大值

class Solution:
    def largestValues(self, root: Optional[TreeNode]) -> List[int]:
        res , queue = [] , collections.deque()
        if not root:
            return []
        queue.append(root)
        while queue:
            temp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                temp.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            Max = max(temp)
            res.append(Max)
        return res

LC 429. N 叉树的层序遍历

N茶树的子节点是用列表存储的, 把二叉树的node.left 和 node.right改成node.children即可,遍历父节点的孩子节点,不为空的加入队列,别的和二叉树的层序遍历无异

class Solution:
    def levelOrder(self, root: 'Node') -> List[List[int]]:
        res , queue = [] , collections.deque()
        if root == None:
            return []
        queue.append(root)
        while queue:
            temp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                temp.append(node.val)

                for child in node.children:
                    if child != None:
                        queue.append(child)
            res.append(temp)
        return res

LC 226. 翻转二叉树

class Solution:
    def swap(self,node):
        if node == None:
            return node
        temp = node.left
        node.left = node.right
        node.right = temp
        self.swap(node.left)
        self.swap(node.right)
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        self.swap(root)
        return root

翻转二叉树,思路是遍历这棵树的同时,交换当前节点的左右孩子

推荐使用前序遍历或后序遍历,注意:交换的是指针,而非节点值

当然,本题层序也能做:

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        queue =  collections.deque([root])
        if not root:
            return None
        while queue:
            temp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                temp.append(node)
                node.left , node.right = node.right , node.left
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

优先掌握层序和前序遍历

LC 101. 对称二叉树

写了很多遍层序遍历之后,其实这题第一反应是用层序遍历+双指针。

思路是层序遍历的同时,将左右孩子节点值加入temp数组中,逐层判断这一层是否是对称的,遍历结束若还没False,就return True,当遇到左右孩子为空时,人为的往temp中加入一个数(比如999),代表此为空,以保证temp数组的长度等于2^k。

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        queue = collections.deque([root])
        if not root:
            return False
        while queue:
            temp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    temp.append(node.left.val)
                    queue.append(node.left)
                else:
                    temp.append(999)
                if node.right:
                    temp.append(node.right.val)
                    queue.append(node.right)
                else:
                    temp.append(999)
            l , r = 0 ,len(temp) - 1
            while l < r:
                if temp[l] != temp[r]:
                    return False
                else:
                    l += 1
                    r -= 1
        return True

temp append 999是因为0,1这样的数会跟二叉树中的节点值混淆,影响结果

当然,卡哥讲的后序遍历也要掌握,思路如下:

首先,最重要的一点感性认知:要判断使用哪种遍历方式,本题要判断是否对称,显然要先递归的查看左子树和右子树是否对称,再返回给上一层节点结果。这就要求必须使用后续遍历,左右中的顺序才能做到。

class Solution:
    def compare(self,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
        #其余情况即为:左右都不为空,且值相等,那么就递归调用,往下一层遍历
        else:
            outside = self.compare(left.left , right.right)
            inside = self.compare(left.right , right.left)
        #调用函数,递归的比较,返回结果
        isSame = outside and inside
        return isSame

    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        return self.compare(root.left , root.right)

说实话,这个方法理解有点困难,总之就是不断地递归遍历,比较二叉树左右子树的外侧是否相等,内侧是否相等、、

LC104 二叉树的最大深度

区分深度和高度:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

高到底,深到顶。求高度,用后序;求深度,用前序。根据定义,根节点的高度,即为树的最大深度。

class Solution:
    def func(self,node):
        #递归出口
        if node == None:
            return 0
            #单层处理逻辑
        leftheight = self.func(node.left)
        rightheight = self.func(node.right)
        depth = 1 + max(leftheight , rightheight)
        #当前节点的高度就是1+孩子节点高度的较大的那个
        return depth
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        return self.func(root)

这道题层序遍历的时间复杂度更好

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root == None:
            return 0
        queue = collections.deque([root])
        count = 0
        while queue:
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            count += 1
        return count

LC 111. 二叉树的最小深度

递归法解答如下,跟最大深度还是有一定区别的

class Solution:
    def getDepth(self, node):
        if node is None:
            return 0
        leftDepth = self.getDepth(node.left)  # 左
        rightDepth = self.getDepth(node.right)  # 右
        
        # 当一个左子树为空,右不为空,这时并不是最低点
        if node.left is None and node.right is not None:
            return 1 + rightDepth
        
        # 当一个右子树为空,左不为空,这时并不是最低点
        if node.left is not None and node.right is None:
            return 1 + leftDepth
        
        result = 1 + min(leftDepth, rightDepth)
        return result

    def minDepth(self, root):
        return self.getDepth(root)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值