196 lines
5.8 KiB
Markdown
196 lines
5.8 KiB
Markdown
## 题目地址
|
||
https://leetcode-cn.com/problems/symmetric-tree/
|
||
|
||
## 思路
|
||
|
||
这是考察二叉树基本操作的经典题目,递归的方式相对好理解一些,迭代法看大家清一色使用队列,其实使用栈也是可以的,只不过遍历的顺序不同而已,关键是要理解只要是对称比较就可以了,遍历的顺序无所谓的。
|
||
|
||
|
||
### 递归法
|
||
|
||
#### 递归三部曲
|
||
|
||
* 确定递归函数的参数和返回值
|
||
* 确定终止条件
|
||
* 确定单层递归的逻辑
|
||
|
||
##### 确定递归函数的参数和返回值
|
||
|
||
判断左右孩子是否对称,所以传入的参数为左指针和右指针,那么就返回是否是对称的就可以了,所以返回值是布尔类型。
|
||
|
||
代码如下:
|
||
```
|
||
bool compare(TreeNode* left, TreeNode* right)
|
||
```
|
||
|
||
##### 确定终止条件
|
||
|
||
* 左孩子为空,右孩子不为空,不对称,return false
|
||
* 左不为空,右为空,不对称 return false
|
||
* 左右都为空,对称,返回true
|
||
* 左右都不为空,比较节点数值,不相同就return false
|
||
|
||
代码如下:
|
||
```
|
||
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;
|
||
```
|
||
|
||
##### 确定单层递归的逻辑
|
||
|
||
* 比较二叉树外侧是否对称:传入的是左孩子的左指针,右孩子的右指针。
|
||
* 比较内测是否对称,传入左孩子的右指针,右孩子的左指针。
|
||
* 如果左右都对称就返回true ,有一侧不对称就返回false 。
|
||
|
||
代码如下:
|
||
|
||
```
|
||
bool outside = compare(left->left, right->right);
|
||
bool inside = compare(left->right, right->left);
|
||
return outside && inside;
|
||
```
|
||
|
||
这样递归的C++代码就写出来了,如下:
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
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);
|
||
}
|
||
};
|
||
```
|
||
|
||
### 迭代法
|
||
|
||
通过队列来判断二叉树内侧和外侧是否相等,如动画所示:
|
||
|
||
<video src='../video/对称二叉树.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
|
||
|
||
代码如下:
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
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;
|
||
}
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
其实使用栈也是可以的,只要把队列原封不动的改成栈就可以了,我下面也给出了代码。
|
||
|
||
## C++代码
|
||
|
||
### 递归
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
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);
|
||
}
|
||
};
|
||
```
|
||
|
||
### 迭代
|
||
|
||
使用队列
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
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;
|
||
}
|
||
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;
|
||
}
|
||
};
|
||
|
||
```
|
||
|
||
使用栈
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
|
||
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
|