Given a binary tree, return the vertical order traversal of its nodes' values. For each node at position (X, Y), its left and right children respectively will be at positions (X-1, Y-1) and (X+1, Y-1).
Running a vertical line from X = -infinity to X = +infinity, whenever the vertical line touches some nodes, we report the values of the nodes in order from top to bottom (decreasing Y coordinate). If two nodes have the same position, then the value of the node that is reported first is the value that is smaller.
Return an list of lists of the values in vertical order.
Example 1:
Input: root = [3,9,20,null,null,15,7]
Output: [[9],[3,15],[20],[7]]
Example 2:
Input: root = [3,9,8,4,0,1,7]
Output: [[4],[9],[3,0,1],[8],[7]]
Example 3:
Input: root = [3,9,8,4,0,1,7,null,null,null,2,5]
Output: [[4],[9,5],[3,0,1],[8,2],[7]]
Can you provide an algorithm that correctly solves this problem? What is the time and space complexity of your solution? Can you identify any edge cases that need to be handled?
A naive approach involves performing a level order traversal of the binary tree and storing the node values along with their column indices in a hash map or dictionary. The column index can be determined by assigning the root node a column index of 0, and then decrementing the column index for left children and incrementing for right children. After the traversal, the hash map can be sorted by column index to retrieve the vertical order traversal.
Algorithm:
column - 1
.column + 1
.The optimal solution also leverages a level-order traversal with a modification to efficiently keep track of the minimum and maximum column indices encountered during the traversal. This eliminates the need for sorting the entire hash map after the traversal.
Algorithm:
min_col
and max_col
to 0.min_col
and max_col
to reflect the minimum and maximum column indices seen so far.column - 1
.column + 1
.min_col
to max_col
and retrieve the values from the hash map for each column index.from collections import defaultdict, deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def verticalOrder(root):
if not root:
return []
column_map = defaultdict(list)
queue = deque([(root, 0)])
min_col, max_col = 0, 0
while queue:
node, col = queue.popleft()
column_map[col].append(node.val)
min_col = min(min_col, col)
max_col = max(max_col, col)
if node.left:
queue.append((node.left, col - 1))
if node.right:
queue.append((node.right, col + 1))
result = []
for col in range(min_col, max_col + 1):
result.append(column_map[col])
return result
column_map
can also store up to N node values.