Day15 二叉树第二天
二叉树的层序遍历
学会层序遍历,直接做10道题。
没错,整整十道题!
LeetCode 102.二叉树的层序遍历
这道题与我们以前遇到的层序遍历不同的地方在于,它要求将每一层的节点都放在一个数组里,最后输出的是一个按层分行的二维数组,所以我们在遍历每一行时要记录这一行的节点个数,将不同行的节点分开。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
vector<vector<int>> res;
if(root) q.push(root);
while(!q.empty()){
int size=q.size();
vector<int> vec;
while(size--){
TreeNode* node=q.front();q.pop();
vec.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
res.push_back(vec);
}
return res;
}
};
LeetCode 107.二叉树的层序遍历II
与上一题一样,把最终结果数组翻转一下即可。
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
queue<TreeNode*> q;
vector<vector<int>> res;
if(root) q.push(root);
while(!q.empty()){
int size=q.size();
vector<int> vec;
while(size--){
TreeNode* node=q.front();q.pop();
vec.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
res.push_back(vec);
}
reverse(res.begin(),res.end());
return res;
}
};
LeetCode 199.二叉树的右视图
此题仍是层序遍历,每次遍历到每一层最后一个元素时将它记录进数组即可。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> q;
vector<int> res;
if(root) q.push(root);
while(!q.empty()){
int size=q.size();
while(size--){
TreeNode* node=q.front();q.pop();
if(size==0) res.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
return res;
}
};
LeetCode 637. 二叉树的层平均值
层序遍历时计算每一层的元素之和,再把平均值加入数组。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode*> q;
vector<double> res;
if(root) q.push(root);
while(!q.empty()){
int size=q.size();
double sum=0;
for(int i=0;i<size;i++){
TreeNode* node=q.front();q.pop();
sum+=node->val;
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
res.push_back(sum/size);
}
return res;
}
};
LeetCode 429. N 叉树的层序遍历
从二叉变为N叉,但其内核还是不变的。
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
queue<Node*> que;
if (root!=NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
for (int i=0;i<size;i++) {
Node* node=que.front();
que.pop();
vec.push_back(node->val);
for (int i=0;i<node->children.size();i++)
if (node->children[i]) que.push(node->children[i]);
}
result.push_back(vec);
}
return result;
}
};
LeetCode 515. 在每个树行中找最大值
层序遍历时每一行找最大值。
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode*> que;
if (root!=NULL) que.push(root);
vector<int> result;
while (!que.empty()) {
int size=que.size();
int maxValue=INT_MIN;
for (int i=0;i<size;i++) {
TreeNode* node=que.front();
que.pop();
maxValue = node->val>maxValue?node->val:maxValue;
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(maxValue);
}
return result;
}
};
LeetCode 116. 填充每个节点的下一个右侧节点指针
层序遍历的单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if (root!=NULL) que.push(root);
while (!que.empty()) {
int size=que.size();
Node* nodePre;
Node* node;
for (int i=0;i<size;i++) {
if (i==0) {
nodePre=que.front(); // 取出一层的头结点
que.pop();
node=nodePre;
} else {
node=que.front();
que.pop();
nodePre->next=node; // 本层前一个节点next指向本节点
nodePre=nodePre->next;
}
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
nodePre->next=NULL; // 本层最后一个节点指向NULL
}
return root;
}
};
LeetCode 117. 填充每个节点的下一个右侧节点指针 II
上一题的解法本身对于非完全二叉树也适用,所以本题可以直接用上一题的代码。
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if (root!=NULL) que.push(root);
while (!que.empty()) {
int size=que.size();
Node* nodePre;
Node* node;
for (int i=0;i<size;i++) {
if (i==0) {
nodePre=que.front(); // 取出一层的头结点
que.pop();
node=nodePre;
} else {
node=que.front();
que.pop();
nodePre->next=node; // 本层前一个节点next指向本节点
nodePre=nodePre->next;
}
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
nodePre->next=NULL; // 本层最后一个节点指向NULL
}
return root;
}
};
LeetCode 104. 二叉树的最大深度
层序遍历一层结束时深度+1。
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;
}
};
LeetCode 111. 二叉树的最小深度
最小深度的意思是只要找到一个左右孩子均为空的节点,那就找到最小深度了。
class Solution {
public:
int minDepth(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);
if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出
return depth;
}
}
}
return depth;
}
};
二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时又发现队列的一个应用了)。
连续打十个,我真棒!
LeetCode 226.翻转二叉树
递归,按照前序遍历的方式前进,在每个节点翻转他的两个子节点即可。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root) return root;
swap(root->left,root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
LeetCode 101. 对称二叉树
对称二叉树的关键是要保证子节点也是对称的,所以要用后序递归遍历树,递归先处理对称的子节点,再将是否对称的结果交给父节点。
class Solution {
public:
bool compare(TreeNode* left,TreeNode* right){
if(!left && !right) return true;
else if(left && !right) return false;
else if(!left && right) return false;
else if(left->val!=right->val) return false;
bool outside=compare(left->left,right->right);
bool inside=compare(left->right,right->left);
bool res=outside&&inside;
return res;
}
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return compare(root->left,root->right);
}
};
又是充实的一天。