📅  最后修改于: 2023-12-03 15:12:42.075000             🧑  作者: Mango
本题为GATE-CS-2014-(Set-1)的第65题。
题目链接:https://gateoverflow.in/2463/gate2014-1-65
给定一棵二叉树,要求将其打印成竖直方向的列。具体来说,对于每一列输出其中的所有节点值。节点的输出顺序是从上到下。
考虑使用哈希表实现。可以用一个哈希表记录每个节点所在的列,并将该节点加入该列的集合中。遍历整棵树,记录每个节点的位置,最后按列号从小到大输出。
代码:
def vertical_order(root):
column_map = {}
min_column = float('inf') # 最左边的列号
max_column = float('-inf') # 最右边的列号
def DFS(node, column, row):
nonlocal column_map, min_column, max_column
if not node:
return
if column not in column_map:
column_map[column] = []
column_map[column].append((row, node.val))
min_column = min(min_column, column)
max_column = max(max_column, column)
DFS(node.left, column - 1, row + 1)
DFS(node.right, column + 1, row + 1)
DFS(root, 0, 0)
result = []
for column in range(min_column, max_column + 1):
column_list = column_map.get(column, [])
column_list.sort()
result.append([val for row, val in column_list])
return result
另一种思路是使用广度优先搜索。按层遍历,每个节点记录它所在的列和行。使用两个哈希表分别记录每一列的最大和最小行号,最后按列号从小到大输出。
代码:
def vertical_order(root):
if not root:
return []
column_map = {}
min_column = float('inf') # 最左边的列号
max_column = float('-inf') # 最右边的列号
queue = [(root, 0, 0)] # 节点队列
while queue:
node, column, row = queue.pop(0)
if column not in column_map:
column_map[column] = []
min_column = min(min_column, column)
max_column = max(max_column, column)
column_map[column].append((row, node.val))
if node.left:
queue.append((node.left, column - 1, row + 1))
if node.right:
queue.append((node.right, column + 1, row + 1))
result = []
for column in range(min_column, max_column + 1):
column_list = column_map[column]
column_list.sort()
result.append([val for row, val in column_list])
return result
两种解法的时间复杂度均为 $O(n\log n)$,其中 $n$ 为节点数。空间复杂度为 $O(n)$。
本题要求将二叉树打印成竖直方向的列,考察了哈希表和树的两种遍历方式。由于哈希表的高效处理能力,方案一在效率上稍胜一筹。在实际问题中,哈希表经常被用于对元素进行快速查找和存储,是一种十分重要的数据结构。