leetcode-master/problems/0101.对称二叉树.md

196 lines
5.8 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 题目地址
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」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。