Grind75第7天 | 543.二叉树的直径、199.二叉树的右视图、297.二叉树的序列化和反序列化

文章讲述了如何在LeetCode上解决关于二叉树的问题,包括计算直径(通过深度递归),获取二叉树的右视图(使用BFS或DFS策略),以及二叉树的序列化和反序列化(利用前序遍历)。
摘要由CSDN通过智能技术生成

543.二叉树的直径

题目链接:https://leetcode.com/problems/diameter-of-binary-tree

解法:

做这个题,首先要搞清楚二叉树深度的定义。二叉树的深度在leetcode里,定义为从根节点到叶子结点的最长路径的节点数(注意不是边的数量)。所以如果只有一个根节点,那么深度为1。

这个题,对于每个节点,都求出直径,再取所有节点直径的最大值。

那么对于每个节点求直径,需要求出左子树的深度和右子树的深度,二者相加就是当前节点的直径。而树的深度为 max(左子树的深度, 右子树深度) + 1,这样通过递归可以求出左子树的深度和右子树的深度。

参考题解:dfs

边界条件:无

时间复杂度:O(n)

空间复杂度:O(height),height为二叉树的高度。

# 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 diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        self.res = 0
        self.dfs(root)
        return self.res
    
    def dfs(self, root):
        if not root:
            return 0
        left_depth = self.dfs(root.left)
        right_depth = self.dfs(root.right)
        # 当前节点为根节点的最长路径
        self.res = max(self.res, left_depth + right_depth)
        # 当前节点为根节点的深度,即为包括所有节点的个数(注意不是边的个数)
        return max(left_depth, right_depth) + 1

199.二叉树的右视图

题目链接:https://leetcode.com/problems/binary-tree-right-side-view

解法:

广度优先搜索:进行BFS层序遍历,把每一层的最后一个(最右边)节点添加到结果集即可。

深度优先搜索:这个思路比较巧妙,在搜索过程中,我们总是先访问右子树。那么对于每一层来说,我们在这层见到的第一个结点一定是最右边的结点。右子树访问到叶子结点了,那么回到根节点,再访问左子树,如果深度大于右子树的深度,那么从右边就可以看到新的节点了。

参考题解:右视图

边界条件:root为null

时间复杂度:O(n)

空间复杂度:O(n)

# 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
# BFS
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        if not root:
            return res
        que = deque([root])
        while que:
            n = len(que)
            for i in range(n):
                node = que.popleft()
                if i == n - 1:
                    res.append(node.val)
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
        return res
# 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
# DFS
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        self.res = []
        self.max_depth = 0
        self.dfs(root, 0)
        return self.res
    
    def dfs(self, root, depth):
        if not root:
            return
        depth += 1
        if depth > self.max_depth:
            self.res.append(root.val)
            self.max_depth = depth
        self.dfs(root.right, depth)
        self.dfs(root.left, depth)

297.二叉树的序列化和反序列化

题目链接:https://leetcode.com/problems/serialize-and-deserialize-binary-tree

解法:

这个题的序列化可以用前序遍历来处理,也就是我们可以用DFS和BFS来进行二叉树的前序遍历。

但是之前重建二叉树的时候不是说过,单凭前序遍历无法重建(反序列化)吗?那是因为二叉树的遍历只保留了非null的值作为结果,而这个题我们把叶子节点的左右空节点也保留在序列化结果中,那么就可以反序列化了。

所以序列化的字符串中包含null值。

这个题的序列化没啥难度,就是标准的前序遍历操作。

反序列麻烦些,涉及递归、队列,要把例子代进去,实际运行一遍才能理解妙处,所以这里不解释了。

参考题解:二叉树的序列化和反序列化

边界条件:无

时间复杂度:O(n)

空间复杂度:O(n)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
# DFS
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return 'x'
        left = self.serialize(root.left)
        right = self.serialize(root.right)
        return ",".join([str(root.val), left, right])

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        data = data.split(',')
        return self.buildTree(data)

    def buildTree(self, data):
        val = data.pop(0)
        if val == 'x': return None
        node = TreeNode(val)
        node.left = self.buildTree(data)
        node.right = self.buildTree(data)
        return node
# BFS
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ''
        que = deque([root])
        res = []
        while que:
            for i in range(len(que)):
                node = que.popleft()
                if node:
                    res.append(str(node.val))
                    que.append(node.left)
                    que.append(node.right)
                else:
                    res.append('x')
        return ','.join(res)

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        if len(data) == 0:
            return None

        data = data.split(',')
        val_que = deque(data)
        root = TreeNode(int(val_que.popleft()))
        node_que = deque([root])
        while node_que:
            node = node_que.popleft()
            left = val_que.popleft()
            right = val_que.popleft()
            if left != 'x':
                left_node = TreeNode(int(left))
                node.left = left_node
                node_que.append(left_node)

            if right != 'x':
                right_node = TreeNode(int(right))
                node.right = right_node
                node_que.append(right_node)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值