Skip to content

Commit

Permalink
Maximum Depth of Binary Tree
Browse files Browse the repository at this point in the history
  • Loading branch information
dksifoua committed Sep 3, 2024
1 parent bd255dc commit a0c5865
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
| 0074 | Medium | Search a 2D Matrix | Array, Binary Search, Matrix | [solution](./docs/0074-Search-A-2D-Matrix.md) |
| 0076 | Hard | Minimum Window Substring | Hash Table, String, Sliding Window | [solution](./docs/0076-Mininum-Window-Substring.md) |
| 0084 | Hard | Largest Rectangle in Histogram | Array, Stack, Monotonic Stack | [solution](./docs/0084-Largest-Rectangle-In-Histogram.md) |
| 0104 | Easy | Maximum Depth of Binary Tree | Tree, Depth-First Search, Breadth-First Search, Binary Tree | [solution](./docs/0104-Maximum-Depth-of-Binary-Tree.md) |
| 0121 | Easy | Best Time to Buy and Sell Stock | Array | [solution](./docs/0121-Best-Time-to-Buy-and-Sell-Stock.md) |
| 0125 | Easy | Valid Palindrome | String, Two Pointers | [solution](./docs/0125-Valid-Palindrome.md) |
| 0128 | Medium | Longest Consecutive Sequence | Array, HashSet | [solution](./docs/0128-Longest-Consecutive-Sequence.md) |
Expand Down
34 changes: 34 additions & 0 deletions docs/0104-Maximum-Depth-of-Binary-Tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/)

## Intuition

The maximum depth of a binary tree is the length of the longest path from the root node to a leaf node. In a binary
tree, we can calculate the depth by recursively finding the maximum depth of the left and right subtrees and adding one
for the current node. This recursive approach naturally explores all paths from the root to each leaf.

## Approach

1. **Base Case:** If the root is null, the depth is 0 because there are no nodes.
2. **Recursive Depth Calculation:**
- Recursively calculate the maximum depth of the left and right subtrees.
- Use `Math.max()` to get the larger depth between the left and right subtrees.
- Add `1` to account for the current node.
3. **Return the Result:** This recursion will return the maximum depth as it propagates back up from the leaf nodes to
the root.

## Complexity

- **Time Complexity: `O(n)`**, where `n` is the number of nodes in the binary tree. Each node is visited once to
calculate its depth.
- **Space Complexity: `O(h)`**, where `h` is the height of the tree. This represents the space used by the call stack
during recursion. In the worst case (a skewed tree), `h = n`, and in the best case (a balanced tree), `h = log(n)`.

## Code

- [Java](../src/main/java/io/dksifoua/leetcode/maximumdepthofbinarytree/Solution.java)

## Summary

This recursive solution calculates the maximum depth of a binary tree by exploring the depth of each subtree and taking
the maximum. It’s a straightforward and efficient approach with `O(n)` time complexity, ensuring that every node
contributes to the final depth calculation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.dksifoua.leetcode.maximumdepthofbinarytree;

import io.dksifoua.leetcode.utils.TreeNode;

public class Solution {

public int maxDepth(TreeNode root) {
if (root == null) return 0;

return 1 + Math.max(this.maxDepth(root.getLeft()), this.maxDepth(root.getRight()));
}
}
93 changes: 93 additions & 0 deletions src/main/java/io/dksifoua/leetcode/utils/TreeNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package io.dksifoua.leetcode.utils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

@AllArgsConstructor
@Getter
@Setter
public class TreeNode {

private int value;
private TreeNode left;
private TreeNode right;

public Integer[] toArray() {
List<Integer> list = new ArrayList<>();

Queue<TreeNode> queue = new LinkedList<>();
queue.add(this);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node != null) {
list.add(node.getValue());

queue.add(node.getLeft());
queue.add(node.getRight());
} else {
list.add(null);
}
}

int i = list.size() - 1;
while (i >= 0 && list.get(i) == null) {
list.remove(i);
i--;
}

return list.toArray(Integer[]::new);
}

public static TreeNode build(Integer[] array) {
if (array == null || array.length == 0) return null;

TreeNode root = new TreeNode(array[0], null, null);

Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);

int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

if (node != null && array[i] != null) {
node.setLeft(new TreeNode(array[i], null, null));
queue.add(node.getLeft());
}
i += 1;

if (node != null && i < array.length && array[i] != null) {
node.setRight(new TreeNode(array[i], null, null));
queue.add(node.getRight());
}
i += 1;
}

return root;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
buildString(builder, "", "");
return builder.toString().trim();
}

private void buildString(StringBuilder builder, String prefix, String childrenPrefix) {
builder.append(prefix).append(value).append("\n");
if (left != null && right != null) {
left.buildString(builder, childrenPrefix + "├── ", childrenPrefix + "│ ");
right.buildString(builder, childrenPrefix + "└── ", childrenPrefix + " ");
} else if (left != null) {
left.buildString(builder, childrenPrefix + "└── ", childrenPrefix + " ");
} else if (right != null) {
right.buildString(builder, childrenPrefix + "└── ", childrenPrefix + " ");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.dksifoua.leetcode.maximumdepthofbinarytree;

import io.dksifoua.leetcode.utils.TreeNode;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class SolutionTest {

static Solution solution = new Solution();

@Test
void test1() {
TreeNode tree = TreeNode.build(new Integer[] { 3, 9, 20, null, null, 15, 7 });
assertEquals(3, solution.maxDepth(tree));
}

@Test
void test2() {
TreeNode tree = TreeNode.build(new Integer[] { 1, null, 2 });
assertEquals(2, solution.maxDepth(tree));
}
}
28 changes: 28 additions & 0 deletions src/test/java/io/dksifoua/leetcode/utils/TreeNodeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.dksifoua.leetcode.utils;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class TreeNodeTest {

@Test
void testBuildFromArray() {
Integer[] array = new Integer[] { 3, 9, 20, null, null, 15, 7 };
TreeNode tree = TreeNode.build(array);
assertEquals("""
3
├── 9
└── 20
├── 15
└── 7""", tree.toString());
}

@Test
void testConvertToArray() {
Integer[] array = new Integer[] { 3, 9, 20, null, null, 15, 7 };
TreeNode tree = TreeNode.build(array);
assertArrayEquals(array, tree.toArray());
}
}

0 comments on commit a0c5865

Please sign in to comment.