226 翻转二叉树
题目
翻转二叉树:
eg:
思路
翻转二叉树就是要翻转每个结点的左右孩子,需要考虑的是用什么顺序来翻转,用前序、后序、层序都可以,中序遍历不可以的原因在于中序遍历是按照左中右的顺序遍历二叉树,我们来模拟一下,先翻转左孩子,然后翻转中间结点,这时翻转后的左孩子变为了右孩子,再翻转右孩子实际上还是对原来的左孩子操作,显然不行。
通过递归来翻转二叉树,先考虑结束条件是根节点为空则不需要翻转,按照后序遍历的顺序来翻转,每次翻转,先翻转左子树,再翻转右子树,然后交换翻转后的左右子树。
迭代法只需要将递归换成相应的先序、后序迭代写法即可。
代码
递归:(后序)
/**
* 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) {
if(!root)
return root;
invertTree(root->left);
invertTree(root->right);
swap(root->left,root->right);
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* cur = st.top();
st.pop();
swap(cur->left,cur->right);
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}
return root;
}
};
101 对称二叉树
题目
检查二叉树是否镜像对称,eg:
思路
检查是否镜像对称,主要是要比较根节点的左右子树是否镜像对称。
①用递归的方法,要同时递归遍历左右子树。需要比较的是外侧的左右子树和内侧的子树是否镜像对称。同时需要先排除掉左右子树只有一个为空或者都为空的情况,只有当左右子树都存在时,且左右结点值相同,才递归比较。
②用比较的方法,要比较的是左右子树外侧的元素和内侧的元素是否相等。考虑用队列将每次比较的左右结点值存下来比较。
代码
①递归
/**
* 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 compare(TreeNode* left,TreeNode* right) {
if(!left && right)
return false;
else if(!right && left)
return false;
else if(!left && !right)
return true;
else if(left->val !=right->val)
return false;
return compare(left->left,right->right) && compare(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(!root)
return true;
return compare(root->left,root->right);
}
};
②迭代
/**
* 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) {
if(!root)
return true;
queue<TreeNode*> que;
que.push(root->left);
que.push(root->right);
while(!que.empty()) {
TreeNode* L = que.front();
que.pop();
TreeNode* R =que.front();
que.pop();
if(!L && R)
return false;
else if(L && !R)
return false;
else if(!L && !R)
continue; //还要继续检查队列是否为空
else if(L->val != R->val)
return false;
que.push(L->left);
que.push(R->right);
que.push(L->right);
que.push(R->left);
}
return true;
}
};
104 二叉树的最大深度
题目
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
要注意叶子节点的判断条件是:左右结点都为空。
思路
①递归。就是找到左右子树的最大深度再加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 maxDepth(TreeNode* root) {
if(!root)
return 0;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return max(leftDepth,rightDepth) + 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 maxDepth(TreeNode* root) {
if(!root)
return 0;
queue<TreeNode*> que;
int count = 0;
que.push(root);
while(!que.empty()) {
int size = que.size();
while(size--) {
TreeNode* cur = que.front();
que.pop();
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
count++;
}
return count;
}
};
111 二叉树的最小深度
题目
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
思路
与求最大深度有所区别,最小深度是从根节点到最近叶子结点,叶子节点是左右孩子都为空的结点,所以可能会存在
这样的情况下,左孩子为空,但最小深度不是1,而应该是右子树的深度+1;因此,在左子树为空,右子树不为空的情况下,最小深度为右子树的最小深度+1;反之,右子树为空,左子树不为空,则为左子树的最小深度+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 minDepth(TreeNode* root) {
if(!root) return 0;
if(!root->left && root->right)
return minDepth(root->right) + 1;
if(root->left && !root->right)
return minDepth(root->left) + 1;
int L = minDepth(root->left);
int R = minDepth(root->right);
return min(L,R) + 1;
}
};
222完全二叉树的节点个数
题目
给定完全二叉树的根节点 root ,求出该树的节点个数。
思路
①递归,即为左子树的节点个数加上右子树的节点个数再+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 countNodes(TreeNode* root) {
if(!root)
return 0;
return countNodes(root->left) + countNodes(root->right) + 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 countNodes(TreeNode* root) {
stack<TreeNode*> st;
int count = 0;
if(!root) return 0;
st.push(root);
count++;
while(!st.empty()) {
TreeNode* cur = st.top();
st.pop();
if(cur->right){
st.push(cur->right);
count++;
}
if(cur->left){
st.push(cur->left);
count++;
}
}
return count;
}
};
110 平衡二叉树
题目
判断二叉树是否为平衡二叉树,平衡二叉树指每个节点的左右两个子树的高度差的绝对值不超过 1。
思路
求高度按照后序遍历,如果左右子树高度差超过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 getHeight(TreeNode* root) {
if(!root)
return 0;
int L = getHeight(root->left);
if(L == -1) return -1;
int R = getHeight(root->right);
if(R == -1) return -1;
if(L > R + 1 || R > L + 1)
return -1;
return max(L,R) + 1;
}
bool isBalanced(TreeNode* root) {
if(getHeight(root) == -1)
return false;
return true;
}
};