## Title Description

This is from niuke.com**“JZ 58 symmetric binary tree”**, difficulty is**“Difficulties”**。

Tag: “sword finger offer”, “binary tree”, “sequence traversal”, “iteration”, “recursion”

Description:

Please implement a function to judge whether a binary tree is symmetrical.

Note that if a binary tree is the same as the mirror image of the binary tree, it is defined as symmetric.

Example 1

```
Input: {8,6,6,5,7,7,5}
Return value: true
```

Example 2

```
Input: {8,6,9,5,7,7,5}
Return value: false
```

requirement:

- Time: 1 s
- Space: 64 m

## basic thought

First of all, it should be clear that the “symmetry” defined by the topic is to consider empty nodes for each layer.

Therefore, if we use the conventional traversal method to check, we need to represent the empty node.

## Local inspection (sequence traversal)

We use`0x3f3f3f3f`

As an invalid value and create a placeholder node`emptyNode`

Used to refer to an empty node（`emptyNode.val = 0x3f3f3f3f`

）。

A simple approach is to use the “sequence traversal” method for “layer by layer inspection”, and for empty nodes`emptyNode`

Reference while ensuring no recursion`emptyNode`

Corresponding child node.

The specific methods are as follows:

- At the beginning, the
`root`

Nodes join the team; - Remove the node from the queue and check whether the node is
`emptyNode`

Node to decide whether to continue to join the team:

- When not
`emptyNode`

When a node, its left / right sons are queued. If there are no left / right sons, it is used`emptyNode`

Substitute for joining the team; - think that
`emptyNode`

Node is ignored;

- During the process, use the “temporary list” to record the information of the current layer, and check whether the current layer meets the “symmetry” requirements;
- Cycle through the process and until the entire queue is empty.

code:

```
import java.util.*;
class Solution {
int INF = 0x3f3f3f3f;
TreeNode emptyNode = new TreeNode(INF);
boolean isSymmetrical(TreeNode root) {
if (root == null) return true;
Deque<TreeNode> d = new ArrayDeque<>();
d.add(root);
while (!d.isEmpty()) {
//Each cycle expands the next layer and coexists in the "queue"
//At the same time, the node values of this layer are successively stored in the "temporary list"
int size = d.size();
List<Integer> list = new ArrayList<>();
while (size-- > 0) {
TreeNode poll = d.pollFirst();
if (!poll.equals(emptyNode)) {
d.addLast(poll.left != null ? poll.left : emptyNode);
d.addLast(poll.right != null ? poll.right : emptyNode);
}
list.add(poll.val);
}
//After each layer is expanded, check whether the layer storing the current layer meets the "symmetry" requirements
if (!check(list)) return false;
}
return true;
}
//Use the "double pointer" to check whether a layer meets the "symmetry" requirement
boolean check(List<Integer> list) {
int l = 0, r = list.size() - 1;
while (l < r) {
if (!list.get(l).equals(list.get(r))) return false;
l++;
r--;
}
return true;
}
}
```

- Time complexity: in the sequence traversal process, each node can join the team at most once, and
`check`

During the symmetry check, each layer is checked only once. Complexity is - Space complexity:

## Global check (recursive)

In the “sequence traversal” solution, we use the “symmetry” definition to check each layer.

In essence, this is a multiple “local” check using the “symmetry” definition.

In fact, we can also use the definition of “symmetry” to check at the “overall” level.

How do we define two subtrees`a`

and`b`

Is it “symmetrical”?

The “symmetry” requirement is met if and only if two subtrees meet the following requirements:

- The root node values of the two sub trees are the same;
- The left and right subtrees of the two subtrees are symmetrical respectively, including:

`a`

Left subtree and`b`

The values at the corresponding positions of the right subtree of the tree are equal`a`

Right subtree and`b`

The values at the corresponding positions of the left subtree of the tree are equal

Specifically, we can design a recursive function`check`

, pass in the head node of the two subtrees to be detected`a`

and`b`

(for this question)`root`

That is, there is the following obvious base case to judge whether the subtree is “symmetrical” in a single query:

`a`

and`b`

All empty nodes: meet the requirements of “symmetry”;`a`

and`b`

One of the nodes is empty, which does not meet the requirement of “symmetry”;`a`

and`b`

The values are not equal and do not meet the requirements of “symmetry”;

In other cases, we should check separately`a`

and`b`

Whether the left and right nodes of are “symmetrical”, that is, recursive calls`check(a.left, b.right)`

and`check(a.right, b.left)`

。

code:

```
class Solution {
public boolean isSymmetrical(TreeNode root) {
return check(root, root);
}
boolean check(TreeNode a, TreeNode b) {
if (a == null && b == null) return true;
if (a == null || b == null) return false;
if (a.val != b.val) return false;
return check(a.left, b.right) && check(a.right, b.left);
}
}
```

- Time complexity: each node is accessed only once. Complexity is
- Space complexity:

## summary

The above two solutions are not only different in implementation, but also different in “starting point”:

- Solution 1: use the method of “sequence traversal” to check the “symmetry” in the unit of “layer”;
- Solution 2: use the method of “recursive tree expansion” to check the “symmetry” in the unit of “subtree”.

When we consider from the overall level, with recursion, we can often write much simpler code than the conventional practice.

I suggest you deepen your understanding of the two different starting points of “part” and “whole”.

## last

This is the third article in our “selected sword fingers” series`58`

The series began on July 1, 2021.

This series will cover all the classic and timeless topics in “sword finger offer”.

While providing the pursuit of “proof” & “ideas”, it also provides the most concise code.

Welcome to pay attention and make a friend ω ・´)