代码随想录刷题随记13-二叉树层次遍历,翻转对称
文章目录
层次遍历
二叉树的层序遍历
leetcode链接
用队列实现
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ret;
if(root==nullptr){
return ret;
}
queue<TreeNode *> myqueue;
myqueue.push(root);
while(!myqueue.empty()){
int size=myqueue.size();
vector<int> tmp;
for(int i=0;i<size;i++){
TreeNode * cur=myqueue.front();
myqueue.pop();
if(cur->left!=nullptr){
myqueue.push(cur->left);
}
if(cur->right!=nullptr){
myqueue.push(cur->right);
}
tmp.push_back(cur->val);
}
ret.push_back(tmp);
}
return ret;
}
};
107.二叉树的层次遍历 II
leetcode链接
这道题和上一题的解题思路是一样的,只有把结果翻转一下就可以了。
pushback改为下述即可
ret.insert(ret.begin(),tmp);
199.二叉树的右视图
leetcode链接
注意这里要用层次遍历的思路来解答。而不能简单的认为就是一直向下遍历最右边的。因为可能存在右边的为空此时最靠外的结点是在左树上面
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> ret;
if(root==nullptr){
return {};
}
TreeNode * cur=root;
queue<TreeNode * > myqueue;
myqueue.push(root);
while(!myqueue.empty()){
int size=myqueue.size();
for(int i=0;i<size;i++){
TreeNode * cur=myqueue.front();
myqueue.pop();
if (i==size-1){
ret.push_back(cur->val);
}
if(cur->left!=nullptr){
myqueue.push(cur->left);
}
if(cur->right!=nullptr){
myqueue.push(cur->right);s
}
}
}
return ret;
}
};
637.二叉树的层平均值
仍然是层次递归的套路,只不过需要计算平均值
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
if(root ==nullptr){
return {};
}
vector<double> ret;
queue<TreeNode *> myque;
myque.push(root);
while(!myque.empty()){
int size=myque.size();
double sum=0;
for(int i=0;i<size;i++){
TreeNode * cur=myque.front();
myque.pop();
sum+=cur->val;
if(cur->left!=nullptr){
myque.push(cur->left);
}
if(cur->right!=nullptr){
myque.push(cur->right);
}
}
ret.push_back((double)sum/(double)size);
}
return ret;
}
};
429.N叉树的层序遍历
leetcode 链接
和二叉树的套路一致,只不过多了一个孩子
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> ret;
if(root==nullptr){
return ret;
}
queue<Node *> myqueue;
myqueue.push(root);
while(!myqueue.empty()){
int size=myqueue.size();
vector<int> tmp;
for(int i=0;i<size;i++){
Node * cur=myqueue.front();
myqueue.pop();
for( Node * child: cur->children){
if(child!=nullptr){
myqueue.push(child);
}
}
tmp.push_back(cur->val);
}
ret.push_back(tmp);
}
return ret;
}
};
515.在每个树行中找最大值
leetcode 链接
和求平均值高度相似了这里不赘述了
116.填充每个节点的下一个右侧节点指针
leetcode链接
有点链表和二叉树结合的意思
class Solution {
public:
Node* connect(Node* root) {
if(root==nullptr)
return root;
queue <Node*> myqueue;
myqueue.push(root);
while( !myqueue.empty()){
int size=myqueue.size();
Node * pre=myqueue.front();
Node * cur;
if(pre->left!=nullptr){
myqueue.push(pre->left);
}
if(pre->right!=nullptr){
myqueue.push(pre->right);
}
myqueue.pop();
for(int i=1;i<size;i++){
cur=myqueue.front();
myqueue.pop();
pre->next=cur;
if(i==size-1){
cur->next=nullptr;
}
if(cur->left!=nullptr){
myqueue.push(cur->left);
}
if(cur->right!=nullptr){
myqueue.push(cur->right);
}
pre=cur;
}
}
return root;
}
};
117.填充每个节点的下一个右侧节点指针II
leetcode 链接
这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,只是需要判断空指针,不过以前也判断了所以没啥影响直接用上一题的代码就可以ac
226.翻转二叉树
递归版本
class Solution {
public:
TreeNode * subtask(TreeNode * root){
if(root->right==nullptr &&root->left==nullptr){
return root;
}
if(root->right==nullptr){
root->left= subtask(root->left);
root->right=root->left;
root->left=nullptr;
return root;
}
if(root->left==nullptr){
root->right= subtask(root->right);
root->left=root->right;
root->right=nullptr;
return root;
}
root->left=subtask(root->left);
root->right=subtask(root->right);
TreeNode *tmp=root->left;
root->left=root->right;
root->right=tmp;
return root;
}
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr){
return nullptr;
}
return subtask(root);
}
};
迭代法
可以利用先序遍历解决
遍历到根的时候翻转一下左右结点,然后深度优先遍历左右孩子继续完成翻转操作
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr){
return nullptr;
}
stack<TreeNode *> mystack;
mystack.push(root);
while(!mystack.empty()){
TreeNode * cur=mystack.top();
mystack.pop();
if(cur->left!=nullptr&&cur->right!=nullptr){
TreeNode * tmp=cur->right;
cur->right=cur->left;
cur->left=tmp;
}
else if(cur->left!=nullptr){
cur->right=cur->left;
cur->left=nullptr;
}
else if(cur->right!=nullptr){
cur->left=cur->right;
cur->right=nullptr;
}
if(cur->right!=nullptr){
mystack.push(cur->right);
}
if(cur->left!=nullptr){
mystack.push(cur->left);
}
}
return root;
}
};
101. 对称二叉树
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树).
使用队列完成
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==nullptr)
return true;
if(root->left==nullptr&&root->right==nullptr){
return true;
}
if((root->left==nullptr&&root->right!=nullptr)||(root->right==nullptr&&root->left!=nullptr)){
return false;
}
queue<TreeNode *> myqueue;
myqueue.push(root->left);
myqueue.push(root->right);
while(!myqueue.empty()){
TreeNode * leftch=myqueue.front();
myqueue.pop();
TreeNode * rightch=myqueue.front();
myqueue.pop();
if(!leftch&&!rightch){
continue;
}
if(!(leftch!=nullptr&&rightch!=nullptr))
return false;
if(leftch->val!=rightch->val)
return false;
myqueue.push(leftch->left);
myqueue.push(rightch->right);
myqueue.push(leftch->right);
myqueue.push(rightch->left);
}
return true;
}
};