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

Binary tree is subtree of Another Tree

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

The below code is a C# function that checks if a binary tree is a subtree of another binary tree. It uses two helper functions: IsSubtree and CheckSubtree.

TreeNode represents a tree node.

class TreeNode {

  public int val;
  public TreeNode left, right;
  public TreeNode(int x) {
    val = x;
    left = null;
    right = null;
  }

}

IsSubtree takes two parameters: root and subRoot, which are the root nodes of the two trees. It returns true if subRoot is a subtree of root and false otherwise.

public bool IsSubtree(TreeNode root, TreeNode subRoot) {

  if (root == null) {
    return false;
  }

  if (CheckSubtree(root, subRoot))
    return true;

  return IsSubtree(root.left, subRoot) || IsSubtree(root.right, subRoot);

}

CheckSubtree takes two parameters: root and subRoot, which are the root nodes of the two trees. It returns true if the two trees are identical and false otherwise.

bool CheckSubtree(TreeNode root, TreeNode subRoot) {

  if (root == null && subRoot == null)
    return true;
  if (root == null || subRoot == null)
    return false;

  if (root.val != subRoot.val) return false;

  return CheckSubtree(root.left, subRoot.left) && CheckSubtree(root.right, subRoot.right);

}

Sure, I’ll try to explain with an example. Suppose we have the following binary trees.

Root

Root

SubRoot

SubRoot

The subRoot tree is a subtree of the root tree because it is identical to the left subtree of the root tree. To find this, the code does the following steps.

To find the result of CheckSubtree, it repeats the same steps as below.

Since CheckSubtree returns false, it means subRoot is not a subtree of root at the current node, so it recursively calls itself with root.left (4) and subRoot (4), and root.right (5) and subRoot (4) as arguments. This will check if the subRoot is a subtree of any of the left or right subtrees of the root.

To find the result of the left recursive call, it repeats the same steps as above:

To find the result of CheckSubtree, it repeats the same steps as below:

To find the result of the left recursive call, it repeats the same steps as below:

To find the result of the right recursive call, it repeats the same steps as below:

The logical AND of the two results for this subtree is true, so this is the return value for this subtree.

Since CheckSubtree returns true, it means subRoot is a subtree of root at this node, so this recursive call returns true as well.

To find the result of the right recursive call, it repeats the same steps as above:

To find the result of CheckSubtree, it repeats the same steps as below:

Since CheckSubtree returns false, it means subRoot is not a subtree of root at this node, so this recursive call returns false as well.

The logical OR of the two results for the whole tree is true because the left recursive call returned true, so this is the final return value.

The time complexity of the code is O(m*n), where m and n are the number of nodes in the two trees. This is because, in the worst case, we have to compare every node in the subRoot tree with every node in the root tree, which takes O(m*n) time. A possible way to optimize the code is to use a hashing technique to compare the trees in O(m+n) time, but this would require extra space.