4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记

LC103 二叉树的锯齿形层序遍历

LC103
在这里插入图片描述

1.读题

给定一个二叉树,返回其节点值的锯齿形层序遍历。

先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行

4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记_第1张图片

2.思路

一看题
啊又是熟悉的层序遍历
变了个花样又拿来考我[doge]

那么我们继续修改广度优先搜索 对二叉树进行逐层遍历
另外 我们使用双端队列 collections.deque() 维护当前层的所有元素

对每层节点的进入队列时的存储 我们维护一个变量isOrderLeft来记录是从左到右插入/从右到左插入

  • 从左到右插入:isOrderLeft=True 每次将遍历到的元素插入双端队列的末尾
  • 从右到左插入:isOrderLeft=False 每次将遍历到的元素插入双端队列的头部

遍历结束的时候我们得到答案数组~

3.C++代码

class Solution {
     
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
     
        vector<vector<int>> ans;
        if(!root) return ans;

        //利用队列实现 BFS按层遍历
        queue<TreeNode*> nodeQueue;//定义一个TreeNode*类的队列 nodeQueue(这个解释不太清楚准不准确 是暂时的一个认知)
        nodeQueue.push(root);
        bool isOrderLeft = true;//记录是否是从左到右插入(true)

        while (!nodeQueue.empty()){
     
            //如果队列不为空 就一直循环下去
            deque<int> levelList;//定义一个双端队列levelList来存储当层的值   
            int size = nodeQueue.size();//size存储了当前层值 方便下面对队列进行遍历
            for (int i=0; i < size; i++){
     //遍历总队列中该层的值并将所有值出队  按标志位存入双端队列 再按固定顺序读取下一层节点值进队列
                auto node = nodeQueue.front();//取出队列第一个值 存储到node中
                nodeQueue.pop();
                if(isOrderLeft) {
     //奇数层 从左到右插入双端队列
                    levelList.emplace_back(node->val);
                }
                else{
     
                    levelList.push_front(node->val);//从容器开头开始插入元素 实现从左往右插入双端队列
                }

                //接下来读取下一层节点值进入双端队列
                if(node->left){
     
                    nodeQueue.push(node->left);//左子节点不为空 就插到总队列中
                }
                if(node->right){
     
                    nodeQueue.push(node->right);
                }
            }
            ans.emplace_back(vector<int>{
     levelList.begin(),levelList.end()});
            //将当前层的值添加到结果数组中
            //前面的vector将队列格式转换格式
            isOrderLeft = !isOrderLeft;
        }
    return ans;
    }
};

4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记_第2张图片

4.python代码

class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        #先层序遍历 再把偶数层的结果翻转即可~
        stack = [root]#总队列 遍历的树暂时都装这里
        ans = []
        while stack:
            level = [] #存储每一层用的队列 其结果直接扔到ans结果数组中
            for _ in range(len(stack)):
                node = stack.pop(0)
                if not node:
                    continue
                level.append(node.val)
                stack.append(node.left)
                stack.append(node.right)
            if level:
                ans.append(level)
        for i in range(1, len(ans), 2):
            ans[i] = ans[i][::-1] #[::-1]是翻转数组的意思 
            #把ans[i]这个数组翻转过来
        return ans

4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记_第3张图片

5.重点

  • 队列的pop操作之前一定要用 .empty() 判空
  • queue nodeQueue
    定义了一个TreeNode类型的队列 取名为nodeQueue
    4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记_第4张图片
  • push_back 在容器尾部添加新的元素
    push_front 在容器开头添加新的元素 这俩正好能用到锯齿遍历中 完美~
  • push_back & emplace_back的区别
    作用相同的——向容器尾部添加元素 不同点在于——
    在这里插入图片描述
    emplace_back()执行效率明显要高一些 实际应用建议优先使用emplace_back()

但是由于 emplace_back() 是 C++ 11 标准新增加的,如果程序要兼顾之前的版本,还是应该使用 push_back()。

  • ans.emplace_back(vector{levelList.begin(),levelList.end()});
    这一句好几个小知识点 (我之前全特么不会 啊我太菜了)
    1.格式转换 从levelList的队列格式转换成vector格式
    2.队列元素获取 用 xx.begin(),xx.end()

  • 矩阵逆向访问(python实现)
    用[::-1]翻转数组
    4-6 LC103二叉树的锯齿形层序遍历 C++ python力扣刷题笔记_第5张图片

你可能感兴趣的:(一个菜鸡的力扣刷题之路,队列,二叉树,c++,数据结构,算法)