Skip to content

Commit

Permalink
Create diff_views_of_binary_tree.py
Browse files Browse the repository at this point in the history
  • Loading branch information
ShareCat committed Nov 8, 2023
1 parent 53d4517 commit 984d089
Showing 1 changed file with 210 additions and 0 deletions.
210 changes: 210 additions & 0 deletions algorithm/data_structures/binary_tree/diff_views_of_binary_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
r"""
Problem: Given root of a binary tree, return the:
1. binary-tree-right-side-view
2. binary-tree-left-side-view
3. binary-tree-top-side-view
4. binary-tree-bottom-side-view
"""

from __future__ import annotations

from collections import defaultdict
from dataclasses import dataclass


@dataclass
class TreeNode:
val: int
left: TreeNode | None = None
right: TreeNode | None = None


def make_tree() -> TreeNode:
"""
>>> make_tree().val
3
"""
return TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7)))


def binary_tree_right_side_view(root: TreeNode) -> list[int]:
r"""
Function returns the right side view of binary tree.
3 <- 3
/ \
9 20 <- 20
/ \
15 7 <- 7
>>> binary_tree_right_side_view(make_tree())
[3, 20, 7]
>>> binary_tree_right_side_view(None)
[]
"""

def depth_first_search(
root: TreeNode | None, depth: int, right_view: list[int]
) -> None:
"""
A depth first search preorder traversal to append the values at
right side of tree.
"""
if not root:
return

if depth == len(right_view):
right_view.append(root.val)

depth_first_search(root.right, depth + 1, right_view)
depth_first_search(root.left, depth + 1, right_view)

right_view: list = []
if not root:
return right_view

depth_first_search(root, 0, right_view)
return right_view


def binary_tree_left_side_view(root: TreeNode) -> list[int]:
r"""
Function returns the left side view of binary tree.
3 -> 3
/ \
9 -> 9 20
/ \
15 -> 15 7
>>> binary_tree_left_side_view(make_tree())
[3, 9, 15]
>>> binary_tree_left_side_view(None)
[]
"""

def depth_first_search(
root: TreeNode | None, depth: int, left_view: list[int]
) -> None:
"""
A depth first search preorder traversal to append the values
at left side of tree.
"""
if not root:
return

if depth == len(left_view):
left_view.append(root.val)

depth_first_search(root.left, depth + 1, left_view)
depth_first_search(root.right, depth + 1, left_view)

left_view: list = []
if not root:
return left_view

depth_first_search(root, 0, left_view)
return left_view


def binary_tree_top_side_view(root: TreeNode) -> list[int]:
r"""
Function returns the top side view of binary tree.
9 3 20 7
⬇ ⬇ ⬇ ⬇
3
/ \
9 20
/ \
15 7
>>> binary_tree_top_side_view(make_tree())
[9, 3, 20, 7]
>>> binary_tree_top_side_view(None)
[]
"""

def breadth_first_search(root: TreeNode, top_view: list[int]) -> None:
"""
A breadth first search traversal with defaultdict ds to append
the values of tree from top view
"""
queue = [(root, 0)]
lookup = defaultdict(list)

while queue:
first = queue.pop(0)
node, hd = first

lookup[hd].append(node.val)

if node.left:
queue.append((node.left, hd - 1))
if node.right:
queue.append((node.right, hd + 1))

for pair in sorted(lookup.items(), key=lambda each: each[0]):
top_view.append(pair[1][0])

top_view: list = []
if not root:
return top_view

breadth_first_search(root, top_view)
return top_view


def binary_tree_bottom_side_view(root: TreeNode) -> list[int]:
r"""
Function returns the bottom side view of binary tree
3
/ \
9 20
/ \
15 7
↑ ↑ ↑ ↑
9 15 20 7
>>> binary_tree_bottom_side_view(make_tree())
[9, 15, 20, 7]
>>> binary_tree_bottom_side_view(None)
[]
"""
from collections import defaultdict

def breadth_first_search(root: TreeNode, bottom_view: list[int]) -> None:
"""
A breadth first search traversal with defaultdict ds to append
the values of tree from bottom view
"""
queue = [(root, 0)]
lookup = defaultdict(list)

while queue:
first = queue.pop(0)
node, hd = first
lookup[hd].append(node.val)

if node.left:
queue.append((node.left, hd - 1))
if node.right:
queue.append((node.right, hd + 1))

for pair in sorted(lookup.items(), key=lambda each: each[0]):
bottom_view.append(pair[1][-1])

bottom_view: list = []
if not root:
return bottom_view

breadth_first_search(root, bottom_view)
return bottom_view


if __name__ == "__main__":
import doctest

doctest.testmod()

0 comments on commit 984d089

Please sign in to comment.