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.
Example 1:
Input: root = [3,4,5,1,2], subRoot = [4,1,2] Output: true
Example 2:
Input: root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2] Output: false
Constraints:
root
tree is in the range [1, 2000]
.subRoot
tree is in the range [1, 1000]
.-104 <= root.val <= 104
-104 <= subRoot.val <= 104
program main
use, intrinsic :: iso_fortran_env, only : error_unit, DP => REAL64
implicit none
integer, parameter :: n = 7
real(kind=DP), dimension(n) :: root = [3._DP, 4._DP, 5._DP, 1._DP, &
2._DP, -1._DP, -2._DP]
real(kind=DP), dimension(n) :: subRoot = [4._DP, 1._DP, 2._DP]
logical :: result
print '(L1)', hasSubtree(root, subRoot)
contains
function hasSubtree(root, subRoot) result(res)
real(kind=DP), intent(in) :: root(:), subRoot(:)
logical :: res
res = .false.
call hasSubtreeRecursive(root, subRoot, 1, res)
end function hasSubtree
recursive subroutine hasSubtreeRecursive(root, subRoot, idx, found)
real(kind=DP), intent(in) :: root(:), subRoot(:)
integer, value :: idx
logical, intent(out) :: found
integer :: i
if (idx > size(root)) then
return
end if
if (root(idx) == subRoot(1)) then
found = .true.
do i = 2, size(subRoot)
if (root(idx+i-1) /= subRoot(i)) then
found = .false.
exit
end if
end do
if (.not. found) then
return
end if
end if
call hasSubtreeRecursive(root, subRoot, idx+1, found)
if (.not. found) then
call hasSubtreeRecursive(root, subRoot, idx+size(root)-idx+1, found)
end if
end subroutine hasSubtreeRecursive
end program main
temp.f95:7:42: 7 | real(kind=DP), dimension(n) :: subRoot = [4._DP, 1._DP, 2._DP] | 1 Error: Different shape for array assignment at (1) on dimension 1 (7 and 3) temp.f95:10:42: 10 | print '(L1)', hasSubtree(root, subRoot) | 1 Error: Symbol ‘subroot’ at (1) has no IMPLICIT type; did you mean ‘root’?
module BinaryTree
implicit none
type :: Node
integer :: val
type(Node), pointer :: left
type(Node), pointer :: right
end type Node
interface
function is_same_tree(root, subRoot) result(same)
type(Node), pointer, intent(in) :: root, subRoot
logical :: same
end function is_same_tree
end interface
contains
function is_subtree(root, subRoot) result(same)
type(Node), pointer, intent(in) :: root, subRoot
logical :: same
same = is_same_tree(root, subRoot)
end function is_subtree
function is_same_tree(root, subRoot) result(same)
type(Node), pointer, intent(in) :: root, subRoot
logical :: same
if (associated(root, subRoot)) then
same = .true.
else if (associated(root)) then
same = is_same_tree(root%left, subRoot) .or. is_same_tree(root%right, subRoot)
else
same = .false.
end if
end function is_same_tree
end module BinaryTree
program main
use BinaryTree
implicit none
type(Node), pointer :: root, subRoot
logical :: same
! Example 1
root => Node(val=3, left=Node(val=4, left=Node(val=1, left=Node(val=2))), right=Node(val=5))
subRoot => Node(val=4, left=Node(val=1, left=Node(val=2)))
same = is_subtree(root, subRoot)
write (*,*) "Example 1: ", same
! Example 2
root => Node(val=3, left=Node(val=4, left=Node(val=1, left=Node(val=2))), right=Node(val=5))
subRoot => Node(val=4, left=Node(val=1, left=Node(val=2, left=Node(val=0))))
same = is_subtree(root, subRoot)
write (*,*) "Example 2: ", same
end program main
temp.f95:12:23: 12 | type(Node), pointer, intent(in) :: root, subRoot | 1 Error: Derived type ‘node’ at (1) is being used before it is defined temp.f95:27:26: 11 | function is_same_tree(root, subRoot) result(same) | 2 ...... 27 | function is_same_tree(root, subRoot) result(same) | 1 Error: Procedure ‘is_same_tree’ at (1) is already defined at (2) temp.f95:28:56: 28 | type(Node), pointer, intent(in) :: root, subRoot | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:29:23: 29 | logical :: same | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:31:43: 31 | if (associated(root, subRoot)) then | 1 Error: Unexpected block IF statement in CONTAINS section at (1) temp.f95:32:25: 32 | same = .true. | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:33:39: 33 | else if (associated(root)) then | 1 Error: Unexpected ELSE IF statement in CONTAINS section at (1) temp.f95:34:38: 34 | same = is_same_tree(root%left, subRoot) .or. is_same_tree(root%right, subRoot) | 1 Error: Symbol ‘root’ at (1) has no IMPLICIT type temp.f95:35:12: 35 | else | 1 Error: Unexpected ELSE statement in CONTAINS section at (1) temp.f95:36:26: 36 | same = .false. | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:37:11: 37 | end if | 1 Error: Expecting END MODULE statement at (1) temp.f95:39:7: 39 | end function is_same_tree | 1 Error: Expecting END MODULE statement at (1) temp.f95:23:15: 23 | same = is_same_tree(root, subRoot) | 1 Error: Type mismatch in argument ‘root’ at (1); passed TYPE(node) to REAL(4) temp.f95:44:9: 44 | use BinaryTree | 1 Fatal Error: Cannot open module file ‘binarytree.mod’ for reading at (1): No such file or directory compilation terminated.
class TreeNode {
constructor(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function isSubtree(root, subRoot) {
if (root === null) return false;
if (isIdentical(root, subRoot)) return true;
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
function isIdentical(n1, n2) {
if (n1 === null || n2 === null) return n1 === n2;
if (n1.val !== n2.val) return false;
return isIdentical(n1.left, n2.left) && isIdentical(n1.right, n2.right);
}
The algorithm checks if subRoot
is a subtree of root
by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then subRoot
is not a subtree at this level, and the algorithm looks further down the left and right branches of root
. This is done by returning the logical OR
between the result of checking left and right branches.
The helper function isIdentical
checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a None
value for a node is found, the two nodes are identical if they are both None
. Otherwise, if the node values differ, the trees are not identical.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
};
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if (root == nullptr) return false;
if (isIdentical(root, subRoot)) return true;
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
bool isIdentical(TreeNode* n1, TreeNode* n2) {
if (n1 == nullptr || n2 == nullptr) return n1 == n2;
if (n1->val != n2->val) return false;
return isIdentical(n1->left, n2->left) && isIdentical(n1->right, n2->right);
}
The algorithm checks if subRoot
is a subtree of root
by first looking whether the two trees have the same root node. If they do, it checks whether the substructures are also identical. If they are not, then subRoot
is not a subtree at this level, and the algorithm looks further down the left and right branches of root
. This is done by returning the logical OR
between the result of checking left and right branches.
The helper function isIdentical
checks whether the two given trees have the same structure and node values, by comparing the current nodes and then recursively traversing the left and right substructures. If a None
value for a node is found, the two nodes are identical if they are both None
. Otherwise, if the node values differ, the trees are not identical.