二叉树——103. 二叉树的锯齿形层序遍历

二叉树——103. 二叉树的锯齿形层序遍历

题目:

思路:

本题可以看成层序遍历的变种,就是输出要求老变,然后可以通过设置一双端队列,用于暂存一层的结点,然后根据当前层数是奇数层还是偶数层决定此队列的读取顺序。

判断是奇数层还是偶数层的具体实现可以通过设置一个变量,去标记本层的读取顺序,遍历完一层后将变量取反即可。

至于读取顺序的实现则依靠双端队列,双端队列是一个可以在队列任意一端插入元素的队列,若读取顺序是从左至右,则每次将遍历到的元素插入至双端队列的末尾;若读取顺序是从右至左,则每次将遍历到的元素插入至双端队列的头部。剩下的就没啥了,可以开始操作了。

代码:

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        // 存放最终答案
        vector<vector<int>> ans;
        if(!root){
            return ans;
        }

        // 结点队列,暂时存放一层的结点
        queue<TreeNode*> nodeQueue;
        nodeQueue.push(root);
        // flag变量标记此层的读取顺序
        bool isOrderLeft = true;

        // 开始遍历
        while(!nodeQueue.empty()){
            // 双端队列 实现不同层的输出需求
            deque<int> levelList;
            // 对于每层的结点开始操作
            int size = nodeQueue.size();
            for(int i = 0; i < size; i++){
                auto node = nodeQueue.front();
                nodeQueue.pop();
                // 若是从左至右,则插入双端队列的末尾
                if(isOrderLeft){
                    levelList.push_back(node->val);
                }else{
                    // 若是从右至左,则插入双端队列的头部
                    levelList.push_front(node->val);
                }
                // 将下一层的结点存入结点队列中,开始下一轮操作
                if(node->left){
                    nodeQueue.push(node->left);
                }
                if(node->right){
                    nodeQueue.push(node->right);
                }
            }
            // emplace_back 其功能和 push_back() 相同,都是在 vector 容器的尾部添加一个元素。
            ans.emplace_back(vector<int>{levelList.begin(), levelList.end()});
            // flag变量取反
            isOrderLeft = !isOrderLeft;
        }
        // 返回最终结果
        return ans;
    }
};

Rank:

Tips:

emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

hhh,最近有点懈怠,效率也不高,得继续加油了,冲冲冲。

posted @ 2021-04-05 23:37  Originhhh  阅读(93)  评论(0)    收藏  举报