[Lc]101对称二叉树
Contents
题解
题解
二叉树结构如下:
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
1. 递归法
class Solution {//三种方法。1、递归法。有点像#100
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;//特殊情况,为空直接返回true
return helper(root->left,root->right);//调用递归函数
}
bool helper(TreeNode* p,TreeNode* q){//这一块和#100很想
if(!p && !q) return true;//都为空返回true,对称
if(!p || !q) return false;//一个为空则为false,不对称
if(p->val != q->val) return false;//左右不相等则返回false
return helper(p->left,q->right) && helper(p->right,q->left);//进行递归
}
};
2. 栈迭代法
class Solution {//三种方法。2、栈迭代法。和先序遍历的迭代法类似
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;//特殊情况,为空直接返回true
stack<TreeNode*> sLeft;
stack<TreeNode*> sRight;//建立存结果的栈
TreeNode *curLeft = root->left;
TreeNode *curRight = root->right;//建立两个指针
while(curLeft || !sLeft.empty() || curRight || !sRight.empty()){
//当指针存在或栈不为空继续迭代
//指针为空可能是到叶子节点,栈为空可能是回到了根节点,这里和先序遍历一样
while(curLeft){//当指针存在继续迭代左子树并压入栈
sLeft.push(curLeft);
curLeft = curLeft->left;
}
while(curRight){//同上
sRight.push(curRight);
curRight = curRight->right;
}
if(sLeft.size() != sRight.size()) return false;//若栈长度不一致返回false
curLeft = sLeft.top(); sLeft.pop();
curRight = sRight.top(); sRight.pop();//到头了之后出栈
if(curLeft->val != curRight->val) return false;//并检测栈顶的值。和中序遍历一样,只是中序遍历是存值,这里是进行比较。
curLeft = curLeft->right;//再进入右子树
curRight = curRight->left;//同上
}
return true;
}
};
3. 队列迭代法
class Solution {//三种方法。3、 队列迭代法。和层次遍历有点类似(广度优先遍历BFS)一层一层比较。
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;//特殊情况,为空直接返回true
queue<TreeNode*> qLeft;
queue<TreeNode*> qRight;//建立两个队列存每一层的值
qLeft.push(root->left);
qRight.push(root->right);//存入根节点的左右子节点
while(!qLeft.empty() && !qRight.empty()){
//当两个队列都有值时,继续循环。注意null也会压入队列,这时队列也不为空。
TreeNode *curLeft = qLeft.front();qLeft.pop();
TreeNode *curRight = qRight.front();qRight.pop();//挨个取出两队列的首值。
if(!curLeft && !curRight) continue;
//当两个都为空时,继续循环。有可能两个对应节点都为空。
if(!curLeft || !curRight) return false;//当其中一个为空,返回false
if(curLeft->val != curRight->val) return false;//当对应值不想动,返回false
qLeft.push(curLeft->left);
qLeft.push(curLeft->right);
qRight.push(curRight->right);
qRight.push(curRight->left);//按对称依次为两个队列压入值。注意此时队列中可能还有上一层的值,但是队列有先进先出的性质,则下一步先计算上一层的值。
}
return true;
}
};
Author ChrisHRZ
LastMod 2020-03-14