题目:226.翻转二叉树
注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果
这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次。
层序遍历亦可。
递归法:
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
swap(root->left, root->right); //中
invertTree(root->left); //左
invertTree(root->right); //右
return root;
}
};
swap函数:(swap
)采用指针作为参数,通过指针修改实际变量的值,即改变指针
迭代法前序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if(root != NULL) st.push(root);
while(!st.empty()){
TreeNode *node = st.top(); //处理中
st.pop();
swap(node->left, node->right);
if(node->left) st.push(node->left); //左
if(node->right) st.push(node->right); //右
}
return root;
}
};
统一迭代法的前序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if(root != NULL) st.push(root);
while(!st.empty()){
TreeNode *node = st.top();
if(node){
st.pop();
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
st.push(node);
st.push(NULL);
}else{
st.pop();
node = st.top();
st.pop();
swap(node->left, node->right);
}
}
return root;
}
};
层序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
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);
swap(node->left, node->right);
}
}
return root;
}
};
题目:101.对称二叉树
尝试作答:果然犯了典型错误:判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点。
思路:
如果左右能翻转,则说明是对称的
考虑遍历顺序:本题只能使用后序,因为需要不断收集左右孩子的信息返回给上一层,而前序遍历(中左右)和中序遍历(左中右)都不能做到这一点。
递归法:
class Solution {
public:
bool compare(TreeNode *left, TreeNode *right){
if(left == NULL && right == NULL) return true; //左右都为空,左右对称
if(left == NULL && right != NULL) return false; //左空右不空,不对称
if(left != NULL && right == NULL) return false; //右空左不空,不对称
if(left->val != right->val) return false; //左右都不空,但值不相等,不对称
//左右都不空且值相等,进入单层循环
bool outside = compare(left->left, right->right); //判断外层——左(右)
bool inside = compare(left->right, right->left); //判断内层——右(左)
bool result = outside && inside; // 中(后序遍历)
return result;
}
bool isSymmetric(TreeNode* root) {
if(root) return compare(root->left, root->right);
else return true;
}
};
迭代法(用栈):
class Solution {
public:
bool isSymmetric(TreeNode* root) {
stack<TreeNode*> st;
if(root){
st.push(root->left);
st.push(root->right);
}
while(!st.empty()){
TreeNode *node1 = st.top();
st.pop(); //自己写时在这个地方犯错误了,一定要取出一个node就pop掉一个
TreeNode *node2 = st.top();
st.pop();
if(node1 == NULL && node2 != NULL) return false;
if(node1 != NULL && node2 == NULL) return false;
if(node1 && node2 && node1->val != node2->val) return false;
if(node1) st.push(node1->left);
if(node2) st.push(node2->right);
if(node1) st.push(node1->right);
if(node2) st.push(node2->left);
}
return true;
}
};
(用队列):和用栈大同小异,略。