dfs
dp
hash table
]
Leetcode 0987. Vertical Order Traversal of a Binary Tree
https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree
First of all, I want to mention, that problem statement is not clear at all, I need to go to comments to understand, what order they expect us to return nodes in levels. So, we have X
coordinate and Y
coordinate, we need to group them by X
coordinate. If we have the same X
coordinate, we need to check:
- First put nodes with higher
Y
coordinates, that ones, which are close to root - If two nodes have the same
Y
coordinate also, we need to put small values before big values.
Let us define dic
, where we create our vertical layers, and self.min_l
and self.max_l
be minimal and maximal numbers of vertical layers. Let us start to traverse our graph, using dfs
, with parameters:
root
is current node we are in nowlvl_h
is horizontal coordinate, that isX
lvl_v
is vertical coordinate, that is-Y
: note, that I increase myY
coordinate as I go down, it is simpler to deal in this way.
Inside dfs
we do the following steps:
- Update
self.min_l
andself.max_l
. - Add
lvl_v
androot.val
pair to our dictionary. We need to add pair to sort it after. - Finally, visit left and right children if it is possible.
In the end, we need to sort each level, and add it to final list of lists.
Complexity: Usual dfs
traversal will take O(n)
time. However we need to sort each level, before we give final result. Let us have w_1, ..., w_h
nodes on each layer. then we need to do w_1 log w_1 + ... + w_h log w_h < n * log W
operations, where W
is width of the biggest layer. So, complexity is O(n log W)
, which potentially can be O(n log n)
, because the widest level can have upto n/2
nodes. Space complexity is O(n)
.
class Solution:
def verticalTraversal(self, root):
dic = defaultdict(list)
self.min_l, self.max_l = float("inf"), -float("inf")
def dfs(root, lvl_h, lvl_v):
self.min_l = min(lvl_h, self.min_l)
self.max_l = max(lvl_h, self.max_l)
dic[lvl_h].append((lvl_v, root.val))
if root.left: dfs(root.left, lvl_h-1, lvl_v+1)
if root.right: dfs(root.right, lvl_h+1, lvl_v+1)
dfs(root, 0, 0)
out = []
for i in range(self.min_l, self.max_l + 1):
out += [[j for i,j in sorted(dic[i])]]
return out
If you like the solution, you can upvote it on leetcode discussion section: Problem 0987