Binary tree oj problem set (LeetCode)

100. Identical trees 

Concerning the recursion problem of trees, always consider two aspects:Return conditions and sub-problems

  1. Consider firstReturn conditions, if the current root nodes are not the same, then return false ( Note, do not judge what is returned when equal, because the current equality does not mean that the subsequent nodes are equal, so what should be returned if it is not equal)
  2. But we also need to consider the case of being empty. If the root nodes of both trees are empty, then true will be returned (only after layer-by-layer comparison, when both trees are empty in the end, true will be returned); if one is empty and the other is empty, then true will be returned. If not empty, return false
  3. Finally consider sub-problem. After comparing the root nodes of the current tree, it is converted into the left subtree and the right subtree for recursive comparison. 
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if (p == NULL && q == NULL)
    {
        return true;
    }

    if (p == NULL || q == NULL)
    {
        return false;
    }

    if (p->val != q->val)
    {
        return false;
    }

    return isSameTree(p->left, q->left)
        && isSameTree(p->right, q->right);
}

965. Single value binary tree 

Idea: The condition for judging a single value is to make the value of the parent node equal to the value of the two children. 

specific method:

  • If it is an empty tree, it returns true (it must reach the end, then all previous value judgments pass)
  • Compare the current node with the value of the left child. If they are not equal, return false (Note, plus conditional judgment to ensure that the left The child is not null to prevent dereferencing of a null pointer)
  • In the same way, the current node is compared with the value of the right child. If they are not equal, false is returned.
  • The lastsubproblem, then the logical AND of the return values ​​​​of the left subtree and the right subtree is returned. As long as the above conditions are not met, Just keep recursing downward
bool isUnivalTree(struct TreeNode* root)
{
    if (root == NULL)
    {
        return true;
    }

    if (root->left && root->val != root->left->val)
    {
        return false;
    }

    if (root->right && root->val != root->right->val)
    {
        return false;
    }

    return isUnivalTree(root->left)
       && isUnivalTree(root->right);
}

101. Symmetric binary tree

 Idea: Because we need to compare the left branch (right branch) of the left subtree with the right branch (left branch) of the right subtree, create a subfunction that accepts two parameters.

specific method:

  1. Returns true if both the left and right subtree root nodes are NULL
  2. If one of the left and right subtree root nodes is empty and the other is not empty, false is returned.
  3. If the left and right subtree root nodes are not empty and are not equal, return false
  4. Sub-problem is divided into: comparing the left branch of the left subtree with the right branch of the right subtree, and comparing the right branch of the left subtree with the left branch of the right subtree , check whether they are symmetrical, and if they are both symmetrical, return true
bool _isSymmetric(struct TreeNode* left, struct TreeNode* right)
{
    if (left == NULL && right == NULL)
    {
        return true;
    }

    if (left == NULL || right == NULL)
    {
        return false;
    }

    if (left->val != right->val)
    {
        return false;
    }

    return _isSymmetric(left->left, right->right)
        && _isSymmetric(left->right, right->left);
}

bool isSymmetric(struct TreeNode* root)
{
    return _isSymmetric(root->left, root->right);
}

144. Preorder traversal of binary tree 

 First of all, what should be noted in this question is that it requires dynamically opening an array, putting the values ​​of the binary tree in the order of preorder traversal, and finally returning the array, so it is different from the direct preorder traversal we did before. It's more complicated.

Specific implementation ideas:

  1. For this question, because the size of the array is uncertain, a return parameter (returnSize) is passed in. Then we write the function to find the number of nodes in the binary tree (for us now, it should be quite simple), Then find the number of nodes and assign it to returnSize
  2. Dynamicly open an array, the size isthe number of binary tree nodesinteger space
  3. Create a pre-order traversal sub-function to truly implement the pre-order traversal order and put the values ​​of the binary tree into the array
  4. Note, if i is passed in here, because it is a local variable, the inner function stack frame i++ during recursion will not affect the outer function stack frame i, causing some values ​​in the array to be overwritten and some values ​​to be uninitialized (random values). Therefore, the correct approach is topass in the address of i and dereference it++

 When i is passed in, a memory error will occur, as shown below:

void _preorderTraversal(struct TreeNode* root, int* a, int* pi)
{
    if (root == NULL)
    {
        return;
    }

    a[(*pi)++] = root->val;
    _preorderTraversal(root->left, a, pi);
    _preorderTraversal(root->right, a, pi);
}

int BTreeSize(struct TreeNode* root)
{
    return root == NULL ? 0 : BTreeSize(root->left) + BTreeSize(root->right) + 1;
}

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    *returnSize = BTreeSize(root);
    int* a = (int*)malloc(*returnSize * sizeof(int));

    int i = 0;
    _preorderTraversal(root, a, &i);

    return a;
}

572. Subtree of another tree

 Idea: This question can be reused. 100. The same tree. The code for this question can be converted into a comparison of any subtree of the root tree to see if it is equal to the subRoot tree. If equal, it means that it is its subtree.

specific method:

  1. Reuse the isSameTree judgment code
  2. Return condition: When the current root subtree and subRoot tree are equal, return true (note that it is meaningless to judge that they are not equal, because they are not equal currently, and you can recurse to the next level to find equality)
  3. Sub-problem: If the current tree itself is not equal to the subRoot tree, then convert it into the left subtree, right subtree and subRoot tree to determine whether they are equal. As long as one side is equal, true will be returned.
  4. Return conditions: Note that if the recursion continues, root may be a null pointer, so if root is NULL, false is returned (because the question stipulates that subRoot must not be empty, so if the subtree is empty, it must not be equal), and at the same time prevent recursion Dereferencing a null pointer
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if (p == NULL && q == NULL)
    {
        return true;
    }

    if (p == NULL || q == NULL)
    {
        return false;
    }

    if (p->val != q->val)
    {
        return false;
    }

    return isSameTree(p->left, q->left)
        && isSameTree(p->right, q->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
    if (root == NULL)
    {
        return false;
    }

    if (isSameTree(root, subRoot))
    {
        return true;
    }

    return isSubtree(root->left, subRoot)
       || isSubtree(root->right, subRoot);
}

Guess you like

Origin blog.csdn.net/2301_79188764/article/details/134492835