title: Daily practice (16): Symmetric binary tree
categories:[Swords offer]
tags:[Daily practice]
date: 2022/02/11
Daily practice (16): Symmetric binary tree
Please implement a function to determine whether a binary tree is symmetric. A binary tree is symmetric if it is the same as its mirror image.
For example, the binary tree [1,2,2,3,4,4,3] is symmetric.
1
/ \
2 2
/ \ / \
3 4 4 3
But the following [1,2,2,null,3,null,3] is not mirror-symmetric:
1
/ \
2 2
\ \
3 3
Example 1:
Input: root = [1,2,2,3,4,4,3]
output: true
Example 2:
Input: root = [1,2,2,null,3,null,3]
output: false
limit:
0 <= number of nodes <= 1000
Source: LeetCode
Link: https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof
method source: Code Caprice
Method 1: Recursion
recursive trilogy
- Determine arguments and return value of recursive function
Because we want to compare whether the two subtrees of the root node are flipped with each other, and then determine whether the tree is a symmetric tree, we need to compare two trees, and the parameters are naturally the left subtree node and the right subtree node.
The return value is naturally of type bool.
Code:
bool compare(TreeNode *left, TreeNode *right)
- determine termination conditions
To compare the value of two nodes to be different, we must first figure out the situation where the two nodes are empty! Otherwise, a null pointer will be manipulated when comparing values later.
The cases where the node is empty are:
- The left node is empty, the right node is not empty, asymmetric, return false
- Left is not empty, right is empty, asymmetric return false
- Both left and right are empty, symmetrical, return true
At this point, the case where the node is empty has been ruled out, so what remains is that the left and right nodes are not empty:
- The left and right are not empty, compare the node values, if they are not the same, return false
At this time, the left and right nodes are not empty, and the values are not the same, we also deal with the situation.
Code:
if (left == NULL && right != NULL) {
return false;
}
else if (left != NULL && right == NULL) {
return false;
}
else if (left == NULL && right == NULL) {
return true;
}
else if (left->val != right->val) {
return false;
}
- Determining the logic of a single-level recursion
At this time, the logic of single-level recursion is entered. The logic of single-level recursion is to deal with the situation that the right node is not empty and the value is the same.
- Compare whether the outside of the binary tree is symmetrical: the left child of the left node is passed in, and the right child of the right node is passed in.
- Compare whether the internal test is symmetrical, pass in the right child of the left node, and the left child of the right node.
- Returns true if the left and right sides are symmetrical, false if one side is asymmetrical.
Code:
bool outside = compare(left->left, right->right); // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left); // 左子树:右、 右子树:左
bool isSame = outside && inside; // 左子树:中、 右子树:中(逻辑处理)
return isSame;
Final overall C++ code:
//1
bool compare(TreeNode* left, TreeNode* right) {
// 首先排除空节点的情况
if (left == NULL && right != NULL) {
return false;
}
else if (left != NULL && right == NULL) {
return false;
}
else if (left == NULL && right == NULL) {
return true;
}
// 排除了空节点,再排除数值不相同的情况
else if (left->val != right->val) {
return false;
}
// 此时就是:左右节点都不为空,且数值相同的情况
// 此时才做递归,做下一层的判断
bool outside = compare(left->left, right->right); // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left); // 左子树:右、 右子树:左
bool isSame = outside && inside; // 左子树:中、 右子树:中 (逻辑处理)
return isSame;
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
return compare(root->left, root->right);
}
//2
bool compare(TreeNode* left, TreeNode* right) {
if (left == NULL && right != NULL) {
return false;
}
else if (left != NULL && right == NULL) {
return false;
}
else if (left == NULL && right == NULL) {
return true;
}
else if (left->val != right->val) {
return false;
} else {
return compare(left->left, right->right) && compare(left->right, right->left);
}
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
return compare(root->left, root->right);
}
Method 2: Iteration (stack/queue)
Use a queue to compare whether two trees (left and right subtrees of the root node) flip each other, the logic is the same as recursion
Determine whether the inner and outer sides of the left subtree and right subtree of the root node are equal
// 迭代
// 队列
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
queue<TreeNode*> que;
que.push(root->left); // 将左子树头结点加入队列
que.push(root->right); // 将右子树头结点加入队列
while (!que.empty()) { // 接下来就要判断这这两个树是否相互翻转
TreeNode* leftNode = que.front(); que.pop();
TreeNode* rightNode = que.front(); que.pop();
if (!leftNode && !rightNode) { // 左节点为空、右节点为空,此时说明是对称的
continue;
}
// 左右一个节点不为空,或者都不为空但数值不相同,返回false
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
return false;
}
que.push(leftNode->left); // 加入左节点左孩子
que.push(rightNode->right); // 加入右节点右孩子
que.push(leftNode->right); // 加入左节点右孩子
que.push(rightNode->left); // 加入右节点左孩子
}
return true;
}
// 栈
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
stack<TreeNode*> st; // 这里改成了栈
st.push(root->left);
st.push(root->right);
while (!st.empty()) {
TreeNode* leftNode = st.top(); st.pop();
TreeNode* rightNode = st.top(); st.pop();
if (!leftNode && !rightNode) {
continue;
}
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
return false;
}
st.push(leftNode->left);
st.push(rightNode->right);
st.push(leftNode->right);
st.push(rightNode->left);
}
return true;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。