题目链接: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
题目链接: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)
题目链接: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