今天学习了二叉树翻转,判断两二叉树是否相等,以及求解二叉树的深度相关问题,分别都使用了递归法和非递归法进行尝试。
226.翻转二叉树
题目链接:226. 翻转二叉树 - 力扣(LeetCode)
这道题目要求将一棵二叉树进行翻转操作。其实基本思想就是把每个点依次进行翻转,首先使用递归的方法。需要注意的是,这个题目并不适合使用中序遍历的方法完成,因为随着根节点的翻转,翻转右子树其实是翻转之前的左子树。这里我们使用前序遍历进行实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void order(TreeNode* root)
{
if(root==NULL) return;
TreeNode* cur=root;
cur=root->left;
root->left=root->right;
root->right=cur;
order(root->left);
order(root->right);
}
TreeNode* invertTree(TreeNode* root) {
order(root);
return root;
}
};
接着使用迭代的方法进行实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if(root) st.push(root);
while(!st.empty())
{
TreeNode* temp=st.top();
st.pop();
TreeNode* cur=temp->left;
temp->left=temp->right;
temp->right=cur;
if(temp->left) st.push(temp->left);
if(temp->right) st.push(temp->right);
}
return root;
}
};
101. 对称二叉树
题目链接:101. 对称二叉树 - 力扣(LeetCode)
这个题目是有些难度的。基本思想是,对于根节点,依次比较左子树的左左子树和右子树的右子树,左子树的右子树和右子树的左子树。从而保证二叉树是一个对称的形态。还是先使用递归的方法进行实现,需要注意的是,对于空结点需要进行单独的判断:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool comp(TreeNode* left,TreeNode* right)
{
if(!left&&right) return false;
else if(left&&!right) return false;
else if(left==NULL&&right==NULL) return true;
else if(left!=NULL&&right!=NULL&&left->val!=right->val) return false;
else{
bool outside=comp(left->left,right->right);
bool inside=comp(left->right,right->left);
bool result=outside&&inside;
return result;
}
}
bool isSymmetric(TreeNode* root) {
bool result=comp(root->left,root->right);
return result;
}
};
使用迭代的方法思路也是一致的:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
stack<TreeNode*> st;
if(root==NULL) return true;
st.push(root->left);
st.push(root->right);
while(!st.empty())
{
TreeNode* l=st.top();
st.pop();
TreeNode* r=st.top();
st.pop();
if(l==NULL&&r==NULL) continue;
if(l!=NULL&&r==NULL) return false;
if(l==NULL&&r!=NULL) return false;
if(l!=NULL&&r!=NULL&&l->val!=r->val) return false;
st.push(l->left);
st.push(r->right);
st.push(l->right);
st.push(r->left);
}
return true;
}
};
104.二叉树的最大深度
题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)
这个题应该是一道很经典的题目。具体做法还是使用递归思想,根节点的深度为左子树深度和右子树深度中的较大值加1得到。递归的终止条件是遇到空结点时,返回0。代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int order(TreeNode* root)
{
if(root==NULL) return 0;
else return max(order(root->left),order(root->right))+1;
}
int maxDepth(TreeNode* root) {
int max=order(root);
return max;
}
};
想使用迭代的方法完成这道题的话,直接使用层次遍历就好了,在遍历过程中对深度进行计数。
111.二叉树的最小深度
题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)
这道题和最大深度的求解相似,但略有一些不同。我一开始的想法是只是简单的将根节点的深度默认为左右子树深度的较小值加一,递归终止条件仍然是空结点为0,这样的话会导致某根节点只有一侧有子树时,他的深度为1.所以我自己完成这道题时,是将空结点返回一个很大的值,叶子结点返回深度1,也过了。属于是投机取巧了。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int order(TreeNode* root)
{
if(root==NULL) return 100010;
else if(root!=NULL&&root->left==NULL&&root->right==NULL) return 1;
else return min(order(root->left),order(root->right))+1;
}
int minDepth(TreeNode* root) {
if(root==NULL) return 0;
else{
int min=order(root);
return min;
}
}
};
比较好的做法是对只有一侧有子树的情况进行单独的判定,这样就可以避免了由空结点造成的问题。实现代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int order(TreeNode* root)
{
if(root==NULL) return 0;
else if(root->left==NULL&&root->right!=NULL) return order(root->right)+1;
else if(root->right==NULL&&root->left!=NULL) return order(root->left)+1;
else return min(order(root->left),order(root->right))+1;
}
int minDepth(TreeNode* root) {
int min=order(root);
return min;
}
};