Lecture 2: Binary Trees (Medium Problems)¶
Helpers¶
In [1]:
from collections import deque
class Node:
def __init__(self,val=0,left=None,right=None):
self.val = val
self.left = left
self.right = right
def to_tree(nums):
n = len(nums)
if n ==0:
return None
root = Node(nums[0])
queue = deque([root])
idx =1
while queue:
node = queue.popleft()
# left child
if idx <n:
val = nums[idx]
if val !=-1:
node.left = Node(val)
queue.append(node.left)
idx +=1
# right child
if idx <n:
val = nums[idx]
if val != -1:
node.right = Node(val)
queue.append(node.right)
idx +=1
return root
root = to_tree([1,2,3,-1,5])
print(root)
<__main__.Node object at 0x103791210>
Zig Zag Traversal Of Binary Tree¶
Given a Binary Tree, print the zigzag traversal of the Binary Tree. Zigzag traversal of a binary tree is a way of visiting the nodes of the tree in a zigzag pattern, alternating between left-to-right and right-to-left at each level.
Input = [1,2,3,4,5,-1,6]
Output = [[1],[3,2],[4,5,6]]
Input = [1,2,-1,4,5,-1,-1,7,8]
Output = [[1],[2],[4,5],[8,7]]
Approach 1 (Modified BFS)¶
In [6]:
from collections import deque
def zig_zag(root):
if not root:
return []
result = []
queue = deque([root])
direction_forward = True
while queue:
node_count = len(queue)
values = []
for _ in range(node_count):
node = queue.popleft()
values.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
if direction_forward:
values.reverse()
result.append(values)
direction_forward = not direction_forward
return result
print(zig_zag(to_tree([1,2,3,4,5,-1,6])))
print(zig_zag(to_tree([1,2,-1,4,5,-1,-1,7,8])))
[[1], [2, 3], [6, 5, 4]] [[1], [2], [5, 4], [7, 8]]
Complexity¶
- N : no of nodes in binary tree
- O(N)
- O(N)
Vertical Order Traversal of Binary Tree¶
Given a Binary Tree, return the Vertical Order Traversal of it starting from the Leftmost level to the Rightmost level. If there are multiple nodes passing through a vertical line, then they should be printed as they appear in level order traversal of the tree.
Input= [1, 2, 3, 4, 10, 9, 11, -1, 5, -1, -1, -1, -1, -1, -1, -1, 6]
Output= [[4],[2,5],[1,10,9,6],[3],[11]]
Input = [2,7,5,2,6,-1,9,-1,-1,5,11,4,-1]
Output = [[2],[7,5],[2,6],[5,11,4],[9]]
Approach 1 (Convert tree to grid)¶
- For each node in a tree we need to track its pos on x axis
- we will make a queue with both nodes and pos
- we can dervice x position from parent
- node.left = node.parent.pos -1
- node.right = node.parent.pos +1
- we will maintain a store[pos]= [node.val]
- Later we will sort the store via pos and form the result
In [ ]:
from collections import deque
def vertical_order(root):
if not root:
return []
result = []
queue = deque([(root,0)])
store = {}
while queue:
(node,pos) = queue.popleft()
if pos not in store:
store[pos]= []
store[pos].append(node.val)
if node.left:
queue.append((node.left,pos-1))
if node.right:
queue.append((node.right,pos+1))
for pos in sorted(store.keys()):
result.append(store[pos])
return result
print(vertical_order(to_tree([1, 2, 3, 4, 10, 9, 11, -1, 5, -1, -1, -1, -1, -1, -1, -1, 6])))
[[4], [2, 5], [1, 10, 9, 6], [3], [11]]
Complexity¶
- N : no of nodes in a tree
- O(N log N)
- O(N)
Top view of a Binary Tree¶
Given a Binary Tree, return its Top View. The Top View of a Binary Tree is the set of nodes visible when we see the tree from the top.
Input = [1,2,3,4,10,9,11,-1,5,-1,-1,-1,-1,-1,-1,-1,6]
Output = [4,2,1,3,11]
Input = [2 ,7 ,5 ,2, 6, -1, 9, -1, -1, 5, 11, 4, -1]
Output = [2,7,2,5,9]
Approach1¶
- We will make use of above approach
- This time we don't need all the nodes
- only the top most node for a given position
In [27]:
from collections import deque
def top_view(root):
if not root:
return []
result = []
queue = deque([(root,0)])
store = {}
while queue:
(node,pos) = queue.popleft()
if pos not in store:
store[pos] = []
store[pos].append(node.val)
if node.left:
queue.append((node.left,pos-1))
if node.right:
queue.append((node.right,pos+1))
for pos in sorted(store.keys()):
result.append(store[pos][0])
return result
print(top_view(to_tree([1,2,3,4,10,9,11,-1,5,-1,-1,-1,-1,-1,-1,-1,6])))
print(top_view(to_tree([2 ,7 ,5 ,2, 6, -1, 9, -1, -1, 5, 11, 4, -1])))
[4, 2, 1, 3, 11] [2, 7, 2, 5, 9]