https://leetcode.com/problems/binary-tree-vertical-order-traversal/#/description
Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column).
If two nodes are in the same row and column, the order should be from left to right.
Examples:
- Given binary tree
[3,9,20,null,null,15,7]
,
3 /\ / \ 9 20 /\ / \ 15 7
return its vertical order traversal as:
[ [9], [3,15], [20], [7] ]
- Given binary tree
[3,9,8,4,0,1,7]
,
3 /\ / \ 9 8 /\ /\ / \/ \ 4 01 7
return its vertical order traversal as:
[ [4], [9], [3,0,1], [8], [7] ]
- Given binary tree
[3,9,8,4,0,1,7,null,null,null,2,5]
(0's right child is 2 and 1's left child is 5),
3 /\ / \ 9 8 /\ /\ / \/ \ 4 01 7 /\ / \ 5 2
return its vertical order traversal as:
[ [4], [9,5], [3,0,1], [8,2], [7] ]
# Definition for a binary tree node. class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = None from collections import defaultdict class Solution(object): def verticalOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ cols = defaultdict(list) s = list() if root: # elements in s have the format of (node, index), where index shows the index/column if this node in the final output list. s.append((root, 0)) while s: node, col = s.pop(0) # for cols dictionary, the key is col/index; the value is node.val cols[col].append(node.val) # the left subnode is on the left side of the tree, and according to the output format, it is at the previous index. if node.left: s.append((node.left, col - 1)) # the right subnode is on the right side of the tree, and according to the output format, it is at the next index. if node.right: s.append((node.right, col + 1)) # return a list. return [cols[k] for k in sorted(cols.keys())]
Usually, a Python dictionary throws aKeyError
if you try to get an item with a key that is not currently in the dictionary. Thedefaultdict
in contrast will simply create any items that you try to access (provided of course they do not exist yet). To create such a "default" item, it calls the function object that you pass in the constructor (more precisely, it's an arbitrary "callable" object, which includes function and type objects). For the first example, default items are created usingint()
, which will return the integer object0
. For the second example, default items are created usinglist()
, which returns a new empty list object.
>>> x
=
[
chr
(i)
for
i
in
range
(
97
,
97
+
26
)]
>>> x
[
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
]
>>>
for
i, v
in
enumerate
(x):
print
(
"{} {}"
.
format
(i, v))
0
a
1
b
2
c
3
d
4
e
5
f
6
g
7
h
8
i
9
j
10
k
11
l
12
m
13
n
14
o
15
p
16
q
17
r
18
s
19
t
20
u
21
v
22
w
23
x
24
y
25
z
Tree Level Order Print - SOLUTION
Given a binary tree of integers, print it in level order. The output will contain space between the numbers in the same level, and new line between different levels. For example, if the tree is:
The output should be:
1
2 3
4 5 6
Solution
It won’t be practical to solve this problem using recursion, because recursion is similar to depth first search, but what we need here is breadth first search. So we will use a queue as we did previously in breadth first search. First, we’ll push the root node into the queue. Then we start a while loop with the condition queue not being empty. Then, at each iteration we pop a node from the beginning of the queue and push its children to the end of the queue. Once we pop a node we print its value and space.
To print the new line in correct place we should count the number of nodes at each level. We will have 2 counts, namely current level count and next level count. Current level count indicates how many nodes should be printed at this level before printing a new line. We decrement it every time we pop an element from the queue and print it. Once the current level count reaches zero we print a new line. Next level count contains the number of nodes in the next level, which will become the current level count after printing a new line. We count the number of nodes in the next level by counting the number of children of the nodes in the current level. Understanding the code is easier than its explanation:
class Node: def __init__(self, val=None): self.left = None self.right = None self.val = val
def levelOrderPrint(tree): if not tree: return nodes=collections.deque([tree]) currentCount, nextCount = 1, 0 while len(nodes)!=0: currentNode=nodes.popleft() currentCount-=1 print currentNode.val, if currentNode.left: nodes.append(currentNode.left) nextCount+=1 if currentNode.right: nodes.append(currentNode.right) nextCount+=1 if currentCount==0: #finished printing current level print '\n', currentCount, nextCount = nextCount, currentCount
The time complexity of this solution is O(N), which is the number of nodes in the tree, so it’s optimal. Because we should visit each node at least once. The space complexity depends on maximum size of the queue at any point, which is the most number of nodes at one level. The worst case occurs when the tree is a complete binary tree, which means each level is completely filled with maximum number of nodes possible. In this case, the most number of nodes appear at the last level, which is (N+1)/2 where N is the total number of nodes. So the space complexity is also O(N). Which is also optimal while using a queue.
Again, this is a very common tree interview question!