第六章二叉树part02
102. 二叉树的层序遍历
思路:自己没想到用队列来解决该问题
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
使用队列实现二叉树广度优先遍历,动画如下:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if(root!=nullptr) que.push(root);
vector<vector<int>> result;
while(!que.empty()){
vector<int> res;
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* node=que.front();
que.pop();
res.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(res);
}
return result;
}
学会二叉树的层序遍历,可以一口气打完以下十题:
- 102.二叉树的层序遍历
- 107.二叉树的层次遍历II
- 199.二叉树的右视图
- 637.二叉树的层平均值
- 429.N叉树的层序遍历
- 515.在每个树行中找最大值
- 116.填充每个节点的下一个右侧节点指针
- 117.填充每个节点的下一个右侧节点指针II
- 104.二叉树的最大深度
- 111.二叉树的最小深度
求最大最小深度也可使用递归
class Solution {
public:
int minDepth(TreeNode* root) {
// queue<TreeNode*> que;
// if(root!=nullptr) que.push(root);
// int depth=0;
// 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);
// if(!node->left&&!node->right) return depth;
// }
// }
// return depth;
if(root==nullptr) return 0;
if(root->left==nullptr&&root->right==nullptr) return 1;
int min_depth=INT_MAX;
if(root->left!=nullptr){
min_depth=min(minDepth(root->left),min_depth);
}
if(root->right!=nullptr){
min_depth=min(minDepth(root->right),min_depth);
}
return min_depth+1;
}
};
226. 翻转二叉树
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]
确定遍历方法,然后遍历每一个节点时左右子节点进行交换。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
//使用层序遍历
// queue<TreeNode*> que;
// if(root!=nullptr) que.push(root);
// while(!que.empty()){
// int size=que.size();
// for(int i=0;i<size;i++){
// TreeNode* node=que.front();
// que.pop();
// TreeNode* tmp;
// if(node->left) que.push(node->left);
// if(node->right) que.push(node->right);
// tmp=node->left;
// node->left=node->right;
// node->right=tmp;
// }
// }
// return root;
//使用递归遍历(前序遍历)
if(root==nullptr) return NULL;
swap(root->left,root->right); //中
invertTree(root->left); //左
invertTree(root->right); //右
return root;
}
};
101. 对称二叉树
给你一个二叉树的根节点 root
, 检查它是否轴对称。
一开始有大概思路但是还是不能完全写出来,对递归还是不太熟悉。
class Solution {
public:
bool compare(TreeNode* left,TreeNode* right){
//终止条件
//首先排除空节点情况
if(left==NULL&&right!=NULL) return false;
if(left!=NULL&&right==NULL) return false;
if(left==NULL&&right==NULL) return true;
//然后排除值不相等情况
if(left->val!=right->val) return false;
//此时左右节点均不为空且数值相等
//单层递归逻辑
return compare(left->left,right->right)&&compare(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
return compare(root->left,root->right);
}
};
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL&&q!=NULL) return false;
if(p!=NULL&&q==NULL) return false;
if(p==NULL&&q==NULL) return true;
if(p->val!=q->val) return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
572. 另一棵树的子树
给你两棵二叉树 root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回 true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树。
使用递归比较两棵树是否相等,使用第二次递归遍历root.
注意isSubtree实现逻辑
class Solution {
public:
bool compare(TreeNode* left,TreeNode* right){
if(left==NULL&&right!=NULL) return false;
if(left!=NULL&&right==NULL) return false;
if(left==NULL&&right==NULL) return true;
if(left->val!=right->val) return false;
return compare(left->left,right->left)&&compare(left->right,right->right);
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if(subRoot==NULL) return true; //subRoot为空,一定为真
if(root==NULL) return false; //root为空,一定为假
return compare(root,subRoot)||isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}
};