Skip to content

Commit fae454f

Browse files
committed
feat(data-structures, binary-tree): mirror binary tree
1 parent dbcbcb5 commit fae454f

30 files changed

Lines changed: 233 additions & 5 deletions

algorithms/sliding_window/max_sum_of_subarray/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def max_sum_subarray(nums: List[int], k: int) -> int:
1010

1111
start = 0
1212
state = 0
13-
max_sum = float('-inf')
13+
max_sum = float("-inf")
1414

1515
for end in range(n):
1616
state += nums[end]

datastructures/trees/binary/test_utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
lowest_common_ancestor_ptr,
77
connect_all_siblings,
88
connect_all_siblings_ptr,
9+
mirror_binary_tree,
910
)
1011
from datastructures.trees.binary.node import BinaryTreeNode
12+
from datastructures.trees.binary.tree.tree_utils import (
13+
create_tree_from_nodes,
14+
level_order_traversal,
15+
)
1116

1217

1318
class LowestCommonAncestorTestCase(unittest.TestCase):
@@ -222,5 +227,25 @@ def test_connect_all_siblings_ptr(self, root: BinaryTreeNode, expected: List[int
222227
self.assertIsNone(current)
223228

224229

230+
MIRROR_BINARY_TREE_TEST_CASES = [
231+
([100, 50, 200, 25, 75, 125, 350], [100, 200, 50, 350, 125, 75, 25]),
232+
([1, 2, None, 3, None, 4], [1, None, 2, None, 3, None, 4]),
233+
([25, 50, 75, 100, 125, 350], [25, 75, 50, None, 350, 125, 100]),
234+
([100], [100]),
235+
([4, 2, 7, 1, 3, 6, 9], [4, 7, 2, 9, 6, 3, 1]),
236+
([], []),
237+
([2, 1, 3], [2, 3, 1]),
238+
]
239+
240+
241+
class MirrorBinaryTreeTestCase(unittest.TestCase):
242+
@parameterized.expand(MIRROR_BINARY_TREE_TEST_CASES)
243+
def test_mirror_binary_tree(self, data: List[int], expected: List[int]):
244+
root = create_tree_from_nodes(data)
245+
actual = mirror_binary_tree(root)
246+
actual_data = level_order_traversal(actual)
247+
self.assertEqual(expected, actual_data)
248+
249+
225250
if __name__ == "__main__":
226251
unittest.main()

datastructures/trees/binary/tree/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,65 @@ Constraints:
391391
![Example 1](./images/examples/minimum_camera_cover_binary_tree_example_1.png)
392392
![Example 2](./images/examples/minimum_camera_cover_binary_tree_example_2.png)
393393
![Example 3](./images/examples/minimum_camera_cover_binary_tree_example_3.png)
394+
395+
---
396+
397+
## Invert Binary Tree
398+
399+
Given the root node of a binary tree, transform the tree by swapping each node’s left and right subtrees, thus creating
400+
a mirror image of the original tree. Return the root of the transformed tree.
401+
402+
### Constraints
403+
404+
- 0 <= `Number of nodes in the tree` <= 100
405+
- -1000 <= `node.value` <= 1000
406+
407+
### Examples
408+
409+
![Example 1](./images/examples/mirror_binary_tree_example_1.png)
410+
![Example 2](./images/examples/mirror_binary_tree_example_2.png)
411+
![Example 3](./images/examples/mirror_binary_tree_example_3.png)
412+
413+
### Solution
414+
415+
For this solution, we do a post-order (left, right, parent) traversal of the binary tree. The algorithm is as follows:
416+
417+
- Perform post-order traversal on the left child of the root node.
418+
- Perform post-order traversal on the right child of the root node.
419+
- Swap the left and right children of the root node.
420+
421+
Since we perform a depth-first search traversal, the children of any node are already mirrored even before we return the
422+
node itself.
423+
424+
Let’s look at an example below:
425+
426+
> Note: In this example, the node at the top of the stack is the current node.
427+
428+
![Solution 1](./images/solutions/mirror_binary_tree_solution_1.png)
429+
![Solution 2](./images/solutions/mirror_binary_tree_solution_2.png)
430+
![Solution 3](./images/solutions/mirror_binary_tree_solution_3.png)
431+
![Solution 4](./images/solutions/mirror_binary_tree_solution_4.png)
432+
![Solution 5](./images/solutions/mirror_binary_tree_solution_5.png)
433+
![Solution 6](./images/solutions/mirror_binary_tree_solution_6.png)
434+
![Solution 7](./images/solutions/mirror_binary_tree_solution_7.png)
435+
![Solution 8](./images/solutions/mirror_binary_tree_solution_8.png)
436+
![Solution 9](./images/solutions/mirror_binary_tree_solution_9.png)
437+
![Solution 10](./images/solutions/mirror_binary_tree_solution_10.png)
438+
![Solution 11](./images/solutions/mirror_binary_tree_solution_11.png)
439+
![Solution 12](./images/solutions/mirror_binary_tree_solution_12.png)
440+
![Solution 13](./images/solutions/mirror_binary_tree_solution_13.png)
441+
![Solution 14](./images/solutions/mirror_binary_tree_solution_14.png)
442+
![Solution 15](./images/solutions/mirror_binary_tree_solution_15.png)
443+
![Solution 16](./images/solutions/mirror_binary_tree_solution_16.png)
444+
445+
#### Time Complexity
446+
447+
The time complexity of this solution is linear O(n), where n is the number of nodes in the tree.
448+
449+
> Note: Every subtree needs to be mirrored, so we visit every node once. Because of that, the runtime complexity is O(n).
450+
451+
#### Space Complexity
452+
453+
The space complexity of this solution is O(h), where h is the height of the tree. This is because our recursive
454+
algorithm uses space on the call stack, which can grow to the height of the binary tree. The complexity will be O(log(n))
455+
for a balanced tree and O(n) for a degenerate tree.

datastructures/trees/binary/tree/binary_tree.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,3 +912,24 @@ def dfs(node: BinaryTreeNode):
912912
camera_count[0] += 1
913913

914914
return camera_count[0]
915+
916+
def invert_tree(self) -> Optional[BinaryTreeNode]:
917+
"""
918+
Inverts this binary tree by swapping each node's left and right subtrees thus creating a mirror image of the
919+
original tree
920+
"""
921+
if not self.root:
922+
return self.root
923+
924+
def invert_tree_helper(
925+
node: Optional[BinaryTreeNode],
926+
) -> Optional[BinaryTreeNode]:
927+
if not node:
928+
return node
929+
930+
inverted_left = invert_tree_helper(node.left)
931+
inverted_right = invert_tree_helper(node.right)
932+
node.left, node.right = inverted_right, inverted_left
933+
return node
934+
935+
return invert_tree_helper(self.root)
27.7 KB
Loading
37.3 KB
Loading
44.6 KB
Loading
26.7 KB
Loading
28.6 KB
Loading
32.7 KB
Loading

0 commit comments

Comments
 (0)