Skip to content

Commit

Permalink
Solve 572 - Subtree of Another Tree (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
terenceponce authored Dec 9, 2023
1 parent b52c50e commit cc2a58e
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 0 deletions.
63 changes: 63 additions & 0 deletions lib/solutions/00572_subtree_of_another_tree/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Subtree of Another Tree

**Link to Problem**: https://leetcode.com/problems/subtree-of-another-tree

## Description

Given the roots of two binary trees `root` and `subRoot`, return `true` if there is a subtree of
root with the same structure and node values of `subRoot` and `false` otherwise.

A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this
node's descendants. The tree `tree` could also be considered as a subtree of itself.

## Examples

### Example 1

```mermaid
graph
A(root) --> B((3))
B --> C((4))
B --> D((5))
C --> E((1))
C --> F((2))
G(subRoot) --> H((4))
H --> I((1))
H --> J((2))
```

```
Input: root = [3,4,5,1,2], subRoot = [4,1,2]
Output: true
```

### Example 2

```mermaid
graph
A((root)) --> B((3))
B --> C((4))
B --> D((5))
C --> E((1))
C --> F((2))
F --> G((0))
F --> H((nil))
I(subRoot) --> J((4))
J --> K((1))
J --> L((2))
```

```
Input: root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
Output: false
```

## Thoughts

Part of the solution for this comes from [100 - Same Tree](../00100_same_tree), so I just reused that.

The thing that I struggled with in this problem was figuring out how to end the recursion and keep it going.

It's actually just really simple, but getting to that solution was not something that just came to me naturally.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
defmodule LeetCodePractice.Solutions.SubtreeOfAnotherTree do
@moduledoc """
Given the roots of two binary trees root and subRoot, return true if there is a subtree of root
with the same structure and node values of subRoot and false otherwise.
A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node's
descendants. The tree tree could also be considered as a subtree of itself.
"""

alias LeetCodePractice.Provisions.TreeNode

@spec call(root :: TreeNode.t() | nil, sub_root :: TreeNode.t() | nil) :: boolean
def call(root, sub_root) do
subtree?(root, sub_root)
end

defp subtree?(nil, nil), do: true
defp subtree?(nil, _), do: false

defp subtree?(root, sub_root) do
if same_tree?(root, sub_root) do
true
else
subtree?(root.left, sub_root) || subtree?(root.right, sub_root)
end
end

defp same_tree?(%TreeNode{val: p_val, left: p_left, right: p_right}, %TreeNode{
val: q_val,
left: q_left,
right: q_right
}) do
if p_val == q_val do
same_tree?(p_left, q_left) && same_tree?(p_right, q_right)
else
false
end
end

defp same_tree?(nil, nil), do: true
defp same_tree?(_, _), do: false
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
defmodule LeetCodePractice.Solutions.SubtreeOfAnotherTreeTest do
use ExUnit.Case, async: true

alias LeetCodePractice.Provisions.TreeNode
alias LeetCodePractice.Solutions.SubtreeOfAnotherTree

test "Case 1 works" do
root = %TreeNode{
val: 3,
left: %TreeNode{
val: 4,
left: %TreeNode{
val: 1,
left: nil,
right: nil
},
right: %TreeNode{
val: 2,
left: nil,
right: nil
}
},
right: %TreeNode{
val: 5,
left: nil,
right: nil
}
}

sub_root = %TreeNode{
val: 4,
left: %TreeNode{
val: 1,
left: nil,
right: nil
},
right: %TreeNode{
val: 2,
left: nil,
right: nil
}
}

assert SubtreeOfAnotherTree.call(root, sub_root) == true
end

test "Case 2 works" do
root = %TreeNode{
val: 3,
left: %TreeNode{
val: 4,
left: %TreeNode{
val: 1,
left: nil,
right: nil
},
right: %TreeNode{
val: 2,
left: %TreeNode{
val: 0,
left: nil,
right: nil
},
right: nil
}
},
right: %TreeNode{
val: 5,
left: nil,
right: nil
}
}

sub_root = %TreeNode{
val: 4,
left: %TreeNode{
val: 1,
left: nil,
right: nil
},
right: %TreeNode{
val: 2,
left: nil,
right: nil
}
}

assert SubtreeOfAnotherTree.call(root, sub_root) == false
end

test "Extra case for 100% test coverage" do
assert SubtreeOfAnotherTree.call(nil, nil) == true
end
end

0 comments on commit cc2a58e

Please sign in to comment.