代码随想录算法训练营第十五天|层序遍历、226.翻转二叉树、101. 对称二叉树

层序遍历

思路:

用size去记录每一层的节点数量,而不是用que.size(),因为que.size()在遍历过程中一直在变化。

需要记住层序遍历的模板!

相关题目

102. 二叉树的层序遍历

代码:
  • 迭代法

/**
 * 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:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>result;
        queue<TreeNode*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            vector<int>vec;
            int size = que.size();
            while(size--)
            {
                TreeNode *node = que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left)
                    que.push(node->left);
                if(node->right)
                    que.push(node->right);
            }
            result.push_back(vec);
        }
        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:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>result;
        int depth = 0;
        Order(root,result,depth);
        return result;
    }

    void Order(TreeNode *cur,vector<vector<int>>& result,int depth)
    {
        if(cur==nullptr)    return;
        if(result.size()==depth)
            result.push_back(vector<int>());
        result[depth].push_back(cur->val);
        Order(cur->left,result,depth+1);
        Order(cur->right,result,depth+1);
    }

};

107. 二叉树的层序遍历 II

代码:
  • 迭代法

/**
 * 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:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>>result;
        queue<TreeNode*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            vector<int>vec;
            while(size--)
            {
                TreeNode *node = que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left)
                    que.push(node->left);
                if(node->right)
                    que.push(node->right);
            }
            result.push_back(vec);
        }
        reverse(result.begin(),result.end());
        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:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>>result;
        int depth = 0;
        Order(root,result,depth);
        reverse(result.begin(),result.end());
        return result;
    }

    void Order(TreeNode *cur,vector<vector<int>>&result,int depth)
    {
        if(cur==nullptr)    return;
        if(result.size()==depth)
            result.push_back(vector<int>());
        result[depth].push_back(cur->val);
        Order(cur->left,result,depth+1);
        Order(cur->right,result,depth+1);
    }

};

199. 二叉树的右视图

代码:
  • 第一次错在没有理解题意,以为只要返回右子树的值即可。

  • 第二次错在没有想到要在什么时候将值加入到数组中

/**
 * 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:
    vector<int> rightSideView(TreeNode* root) {
        vector<int>result;
        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();
                if(i==(size-1))
                {
                    result.push_back(node->val);
                }
                if(node->left)
                    que.push(node->left);
                if(node->right)
                    que.push(node->right);
            }
        }
            
        return result;
    }
};

637. 二叉树的层平均值

代码:
/**
 * 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:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double>result;
        queue<TreeNode*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            double total = 0;
            for(int i = 0;i<size;i++)
            {
                TreeNode *node = que.front();
                que.pop();
                total+=node->val;
                if(node->left)  que.push(node->left);
                if(node->right)  que.push(node->right);
            }
            result.push_back(total/size);
        }
        return result;

    }
};

429. N 叉树的层序遍历

代码:
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>>result;
        queue<Node*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            vector<int>vec;
            for(int i = 0;i<size;i++)
            {
                Node *cur = que.front();
                que.pop();
                vec.push_back(cur->val);
                for(int j = 0;j<cur->children.size();j++)
                {
                    if(cur->children[j])
                        que.push(cur->children[j]);
                }
            }
            result.push_back(vec);
        }
        return result;
    }
};

515. 在每个树行中找最大值

代码:
  • 第一次错是因为没看到还有负数值

/**
 * 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:
    vector<int> largestValues(TreeNode* root) {
        vector<int>result;
        queue<TreeNode*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            int Max = INT_MIN;
            for(int i = 0;i<size;i++)
            {
                TreeNode *node = que.front();
                que.pop();
                Max = max(node->val,Max);
                if(node->left)  que.push(node->left);
                if(node->right)  que.push(node->right);
            }
            result.push_back(Max);
        }
        return result;
    }
};

116. 填充每个节点的下一个右侧节点指针

代码:
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            for(int i = 0;i<size;i++)
            {
                Node *cur = que.front();
                que.pop();
                if(i!=(size-1))
                    cur->next = que.front();
                else
                    cur->next = nullptr;
                if(cur->left)   que.push(cur->left);
                if(cur->right)  que.push(cur->right);
            }
        }
        return root;
    }
};

117. 填充每个节点的下一个右侧节点指针 II

代码:
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*>que;
        if(root!=nullptr)
            que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            for(int i = 0;i<size;i++)
            {
                Node *cur = que.front();
                que.pop();
                if(i!=(size-1))
                    cur->next = que.front();
                else
                    cur->next = nullptr;
                if(cur->left)   que.push(cur->left);
                if(cur->right)  que.push(cur->right);
            }
        }
        return root;
    }
};

104. 二叉树的最大深度

代码:
/**
 * 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) {
        queue<TreeNode*>que;
        if(root!=nullptr)   que.push(root);
        int depth = 0;

        while(!que.empty())
        {
            int size = que.size();
            while(size--)
            {
                TreeNode *node = que.front();
                que.pop();
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
            }
            depth++;
        }
        return depth;
    }
};

111. 二叉树的最小深度

代码:
  • 迭代法

/**
 * 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) {
        queue<TreeNode*>que;
        if(root!=nullptr)   que.push(root);
        int depth = 0;
        while(!que.empty())
        {
            int size = que.size();
            depth++;
            while(size--)
            {
                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 翻转二叉树

题目链接:https://leetcode.cn/problems/invert-binary-tree/

思路:

采用遍历的方式对二叉树进行”翻转“,即将左右子树进行交换。注:递归遍历中的中序遍历不能直接使用。

代码:

  • 前序遍历(递归遍历)

/**
 * 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) {
        inver(root);
        return root;

    }

    void inver(TreeNode *cur)
    {
        if(cur==nullptr)    return;
        /*
        TreeNode *tmp = cur->left;
        cur->left = cur->right;
        cur->right = tmp;
        */
        swap(cur->left,cur->right);
        inver(cur->left);
        inver(cur->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:
    TreeNode* invertTree(TreeNode* root) {
        stack<TreeNode*>st;
        if(root==nullptr)   return root;
        st.push(root);
        while(!st.empty())
        {
            TreeNode *node = st.top();  //中
            st.pop();
            swap(node->left,node->right);

            if(node->left)  st.push(node->left);    //左
            if(node->right) st.push(node->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) {
        queue<TreeNode*>que;
        if(root!=nullptr)   que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            while(size--)
            {
                TreeNode *node = que.front();
                que.pop();
                swap(node->left,node->right);
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return root;
    }
};

总结

自己写的话写出来了递归遍历的前序遍历。以后做二叉树的题目需要好好思考使用哪种遍历方式来做。

LeetCode 101 对称二叉树

题目链接:https://leetcode.cn/problems/symmetric-tree/

思路:

判断是否是对称二叉树即判断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:
    bool isSymmetric(TreeNode* root) {
        return compare(root->left,root->right);

    }

    bool compare(TreeNode *left,TreeNode *right)
    {
        if(!left&&right)    return false;
        else if(left&&!right)   return false;
        else if(!left&&!right)  return true;
        else if(left->val!=right->val)  return false;
        bool outside = compare(left->left,right->right); //左子树的左节点和右子树的右节点比较,即树的外侧比较
        bool inside = compare(left->right,right->left);  //左子树的右节点和右子树的左节点比较,即树的内侧比较
        bool isSame = inside&&outside;  //将信息返回给父节点,即后序遍历中的中

        return isSame;
    }

};
  • 队列-迭代法

/**
 * 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) {
        queue<TreeNode*>que;
        if(root==nullptr)   return true;
        que.push(root->left);
        que.push(root->right);
        while(!que.empty())
        {
            TreeNode *left = que.front();
            que.pop();
            TreeNode *right = que.front();
            que.pop();

            if(!left&&!right)   continue;

            if((!left||!right||left->val!=right->val))
                return false;
            
            que.push(left->left);   // 左子树的左节点   外
            que.push(right->right); // 右子树的右节点   外
            que.push(left->right);  // 左子树的右节点   内
            que.push(right->left);  // 右子树的左节点   内
        }
        return true;
    }
};
  • 栈-迭代法

/**
 * 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==nullptr)   return true;
        st.push(root->left);
        st.push(root->right);
        while(!st.empty())
        {
            TreeNode *left = st.top();
            st.pop();
            TreeNode *right = st.top();
            st.pop();

            if(!left&&!right)   continue;

            if((!left||!right||left->val!=right->val))
                return false;
            
            st.push(left->left);   // 左子树的左节点   外
            st.push(right->right); // 右子树的右节点   外
            st.push(left->right);  // 左子树的右节点   内
            st.push(right->left);  // 右子树的左节点   内
        }
        return true;
    }
};

总结

在做题的时候还需要先思考使用哪种遍历方式或者题目和哪种遍历方式接近,多加练习。

今日总结:

还需要多加练习,第一次接触二叉树的题目,基本都要先看视频再去做。希望二刷可以有所改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值