【LeetCode笔记】Binary Tree Zigzag Level Order Traversal 二叉树Z字形遍历

本文介绍了一种二叉树的锯齿形层次遍历算法,使用vector代替队列,并通过奇偶判断控制节点的读取顺序,实现了从左到右和从右到左交替遍历。

思路:

其实和上一题(二叉树的按层遍历)很像,开始想的是用队列存入一层的节点,这时计算队列的size,然后想要从第size个开始反过来取。咦,这不是先进后出嘛,用stack呀!不对,每取出来一个节点,都要继续存入这个节点的左右子节点,那不是这一层还没取完下一层就压栈进来了。既然想要根据位置存取方便,那当然是用vector!第二个问题在于从左往右存和从右往左存是每层交叉的,所以还需要多一个判断(这里我用奇偶来判断)

关键点:1.不用queue,用vector。2.从左往右和从右往左需要用奇偶判断下。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> v;
        TreeNode* p;
        vector<TreeNode*> q; //这里用vector来当每一层节点的临时容器,代替了上一题的queue
        if (root==NULL)
            return v;
        else{
            q.push_back(root);
            int n = 2;
            while (!q.empty()){
                vector<int> v2;
                int size = q.size();
                for (int i = size; i > 0; i--){
                    p = q[i-1];
                    v2.push_back(p->val);
                    q.erase(q.begin()+i-1);
                    if(n%2==0){
                        if(p->left!=NULL)
                            q.push_back(p->left);
                        if(p->right!=NULL)
                            q.push_back(p->right);
                    }
                    else{
                        if(p->right!=NULL)
                            q.push_back(p->right);
                        if(p->left!=NULL)
                            q.push_back(p->left);
                    }
                }
                v.push_back(v2);
                n = (n+1)%2;
            }
        }
        return v;
    }
};

反思:刚开始刷题,对vector的操作函数还不太熟悉~需要多练习
### Z字形遍历算法概述 Z字形遍历是一种特殊的二叉树层序遍历方式,其特点是按照从左至右和从右至左交替的方式逐层访问节点。这种遍历通常用于解决一些涉及层次结构的问题,并且可以通过双端队列(`Deque`)来高效实现。 以下是基于提供的引用内容以及专业知识对Z字形遍历算法的题目、实现方法及相关细节的详细介绍: --- #### 1. **Z字形遍历的核心概念** Z字形遍历的关键在于控制每一层的遍历方向。通过引入一个布尔变量 `flag` 来标记当前层是从左至右还是从右至左进行遍历[^4]。当 `flag` 为真时,表示该层按正常顺序处理;反之,则需反向操作。 为了存储每层的结果并支持灵活的方向调整,可以利用双端队列(`Deque`)。它允许在一侧添加或移除元素的同时保持另一侧不变,从而简化了逻辑设计[^2]。 --- #### 2. **典型LeetCode题目** - **LeetCode 103: Binary Tree Zigzag Level Order Traversal (二叉树的锯齿形层序遍历)** 此题正是针对二叉树执行Z字形遍历的经典案例之一。目标是以特定模式返回各层结点值列表集合,其中奇数编号层数组应呈现常规排列而偶数编号则相反。 输入示例: ```plaintext 3 / \ 9 20 / \ 15 7 ``` 输出结果: ```plaintext [ [3], [20, 9], [15, 7] ] ``` 上述例子展示了如何依据指定规则构建最终答案数组形式。 --- #### 3. **具体实现方法** 下面提供了一种采用Java语言完成的解决方案框架,遵循O(n)的时间复杂度与空间需求标准[^3]: ```java import java.util.*; public class BinaryTreeZigzagLevelOrderTraversal { public static List<List<Integer>> zigzagLevelOrder(TreeNode root){ List<List<Integer>> result = new ArrayList<>(); if(root == null){ return result; } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); boolean leftToRight = true; while(!queue.isEmpty()){ int levelSize = queue.size(); Deque<Integer> deque = new LinkedList<>(); for(int i=0;i<levelSize;i++){ TreeNode currentNode = queue.poll(); // 根据标志位决定加入deque的位置 if(leftToRight){ deque.addLast(currentNode.val); }else{ deque.addFirst(currentNode.val); } if(currentNode.left !=null){ queue.offer(currentNode.left); } if(currentNode.right!=null){ queue.offer(currentNode.right); } } result.add(new ArrayList<>(deque)); leftToRight=!leftToRight; // 反转方向 } return result; } public static void main(String[] args){ // 测试代码省略... } } ``` 在此段程序里,我们运用了一个辅助性的双向链表(`Deque`)作为临时容器,在每次迭代过程中动态调节数值插入位置以达成预期效果^。 --- #### 4. **性能分析** 整个过程仅需一次完整的广度优先搜索即可覆盖整棵树的所有节点,因此总体时间开销维持在线性级别即 O(n) 。与此同时,额外使用的内存容量也严格受限于待处理的最大单层规模大小范围内,故同样满足线性增长规律下的空间消耗要求 O(n). ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值