反转二叉树
递归写法
很简单
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr)return root;
TreeNode* tmp;
tmp=root->left;
root->left=root->right;
root->right=tmp;
invertTree(root->left);
invertTree(root->right);
return root;
}
};
迭代写法
先序遍历
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> sta;
if(root)sta.push(root);
TreeNode* cur;
while(!sta.empty()){
cur=sta.top();
sta.pop();
if(cur->left)sta.push(cur->left);
if(cur->right)sta.push(cur->right);
TreeNode* tmp=cur->left;
cur->left=cur->right;
cur->right=tmp;
}
return root;
}
};
后序也可以;
但是中序遍历不行;
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> sta;
if(root)sta.push(root);
TreeNode* cur;
while(!sta.empty()){
cur=sta.top();
sta.pop();
if(cur){
if(cur->right)sta.push(cur->right);
sta.push(cur);
sta.push(nullptr);
if(cur->left)sta.push(cur->left);
}else{
cur=sta.top();
sta.pop();
TreeNode* tmp=cur->left;
cur->left=cur->right;
cur->right=tmp;
}
}
return root;
}
};
但是这个是可以过oj的
对称二叉树
反转之后再和原来的树比较,一模一样就是对称的。
但是这样还要复制一棵树,浪费空间。
应该两个指针同时遍历,镜像遍历:
只能是后序遍历?
- 前序遍历
这种情况会出现假阳性,根本在于前序遍历不能唯一标识一棵树
- 中序遍历
同理,中序遍历也不能唯一标识一棵树:加法的二义性
- 后序遍历
后序遍历也不能唯一标识一棵树,例子同前序遍历的例子。
所以:并非只有后序遍历才行
class Solution {
public:
bool Compare(TreeNode* cur1,TreeNode* cur2){
if(cur1->left&&cur2->right){
if(cur1->left->val!=cur2->right->val)return 0;
}else if(cur1->left&&!cur2->right){
return 0;
}else if(!cur1->left&&cur2->right){
return 0;
}
if(cur2->left&&cur1->right){
if(cur2->left->val!=cur1->right->val)return 0;
}else if(cur2->left&&!cur1->right){
return 0;
}else if(!cur2->left&&cur1->right){
return 0;
}
return 1;
}
bool isSymmetric(TreeNode* root) {
stack<TreeNode*> sta1;
stack<TreeNode*> sta2;
if(root){
sta1.push(root);
sta2.push(root);
}
TreeNode* cur1,*cur2;
while(!sta1.empty()&&!sta2.empty()){
cur1=sta1.top();
sta1.pop();
cur2=sta2.top();
sta2.pop();
if(!Compare(cur1,cur2))return 0;
if(cur1->right)sta1.push(cur1->right);
if(cur1->left)sta1.push(cur1->left);
if(cur2->left)sta2.push(cur2->left);
if(cur2->right)sta2.push(cur2->right);
}
return 1;
}
};
只需要在比较时添加上子节点的因素,就可以避免假阳性
二叉树最大深度
层序遍历
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode*> que;
if(root) que.push(root);
int cur_size=1,nxt_size=0;
int depth=0;
while(!que.empty()){
TreeNode* cur=que.front();
que.pop();
if(cur->left){
nxt_size++;
que.push(cur->left);
}
if(cur->right){
nxt_size++;
que.push(cur->right);
}
if(--cur_size==0){
depth++;
cur_size=nxt_size;
nxt_size=0;
}
}
return depth;
}
};
更简洁的写法:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == NULL) return 0;
int depth = 0;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()) {
int size = que.size();
depth++; // 记录深度
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return depth;
}
};
二叉树最小深度
层序遍历
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode*> que;
if(root) que.push(root);
int cur_size=1,nxt_size=0;
int depth=0;
while(!que.empty()){
TreeNode* cur=que.front();
que.pop();
if(!cur->left&&!cur->right)return depth+1;
if(cur->left){
nxt_size++;
que.push(cur->left);
}
if(cur->right){
nxt_size++;
que.push(cur->right);
}
if(--cur_size==0){
depth++;
cur_size=nxt_size;
nxt_size=0;
}
}
return depth;
}
};
->right){
nxt_size++;
que.push(cur->right);
}
if(–cur_size==0){
depth++;
cur_size=nxt_size;
nxt_size=0;
}
}
return depth;
}
};
> 判断有没有叶节点