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 <= 104program 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.