# Leetcode Symmetric-Tree

#### 2022-07-05 10:15

> ##### Algorithms:
>
> #algorithm #DFS #recursion #BFS
>
> ##### Data structures:
>
> #DS #binary_tree
>
> ##### Difficulty:
>
> #coding_problems #difficulty_easy
>
> ##### Additional tags:
>
> #leetcode
>
> ##### Revisions:
>
> N/A

##### Related topics:

##### Links:

- [Link to problem](https://leetcode.com/problems/symmetric-tree/)

  ***

### Problem

Given the `root` of a binary tree, _check whether it is a mirror of itself_ (i.e., symmetric around its center).

#### Examples

**Example 1:**

![](https://assets.leetcode.com/uploads/2021/02/19/symtree1.jpg)

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

**Example 2:**

![](https://assets.leetcode.com/uploads/2021/02/19/symtree2.jpg)

**Input:** root = [1,2,2,null,3,null,3]
**Output:** false

#### Constraints

**Constraints:**

- The number of nodes in the tree is in the range `[1, 1000]`.
- `-100 <= Node.val <= 100`

### Thoughts

> [!summary]
> This is a #DFS #recursion problem

Method 1, DFS-like Recursion:

- Base Cases:
  - left and right are nullptr: true
  - else if left or right is nullptr: false, must be asymmetric
  - left->val != right->val: false
- return check(left->left, right->right) && check(left->right, right->left)

  Method 2, BFS-like Iteration:
  In the while loop:

- Take two nodes from queue, they should be matched.
- if both are nullptr, continue.
- if one is nullptr, return false.
- if val doesn't match, return false.
- add left->left and right->right to queue (they will be matched as a pair)
- add left->right and right->left to queue (they will be matched as a pair)

### Solution

Recursion, 16ms

```cpp
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
bool checkSymmetric(TreeNode *left, TreeNode *right) {
  // If only one child is leaf it is not symmetric
  if (!left && !right) {
    return true;
  } else if (!left || !right) {
    return false;
  }

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

  // One node has two childs, traverse them in pairs.
  return checkSymmetric(left->right, right->left) &&
         checkSymmetric(left->left, right->right);
}

public:
bool isSymmetric(TreeNode *root) {
  // DFS-like recursion
  return checkSymmetric(root->left, root->right);
}
};
```

BFS, iteration, 8ms

```cpp
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
bool checkLeaves(TreeNode *l, TreeNode *r) {
  // Check if the leaves are symmetric.
  if (!l && !r) {
    return true;
  } else if (!l || !r) {
    return false;
  }
  return true;
}

public:
bool isSymmetric(TreeNode *root) {
  // BFS-like iteration, using queue.

  // Ensure root has two childs
  if (!checkLeaves(root->left, root->right)) {
    return false;
  }

  queue<TreeNode *> pending;
  pending.push(root->left);
  pending.push(root->right);

  TreeNode *l, *r;

  while (!pending.empty()) {
    l = pending.front();
    pending.pop();
    r = pending.front();
    pending.pop();

    if (l && r) {
      // Check val of l and r
      if (l->val != r->val) {
        return false;
      }
      // Chech if the child nodes are symmetric
      if (!(checkLeaves(l->left, r->right) &&
            checkLeaves(l->right, r->left))) {
        return false;
      }

      // Add more to queue
      pending.push(l->left);
      pending.push(r->right);
      pending.push(l->right);
      pending.push(r->left);
    }
  }

  return true;
}
};
```
