OJ:LeetCode 102 103 层序遍历两则 - BFS+额外标记

本文介绍如何实现二叉树的层序遍历及正反交替层序遍历算法,包括详细的解题思路和C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

层序遍历

102. Binary Tree Level Order Traversal

Given the root of a binary tree, return the level order traversal of its nodes’ values. (i.e., from left to right, level by level).

Example 1:

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]

Example 2:

Input: root = [1]
Output: [[1]]

Example 3:

Input: root = []
Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 2000].
  • -1000 <= Node.val <= 1000

题解

解题思路

首先,通过构建和维护一个bfs队列来执行层序遍历;在此基础上,在bfs队列中每一层的末尾加入NULL来指示这一层的结束。

首先在bfs队列中入队root和null,即第一层的内容.在之后的循环中,不断移出队首的元素并将其子节点加入队列。使用一个额外的vector记录每一层的节点值(val),如果判断某一个节点是这一层的最后一个节点(即bfs队列中其下一位是null),则把这个vector的内容作为这一层的内容,并把vector清空,准备承接下一层的内容。同时,如果判断某一个节点是这一层的最后一个节点,需要在子节点入队后额外入队一个null标志下一层的结束。通过维护bfs队列中的null标志,可以

在实现时注意到,最后的空层会连续地引入两个null为最终的终结。所以我们这里在result.push_back的时候不允许参数为空层。也可以通过检测到两个null时提前break掉循环的方式实现。

结果

执行用时 : 0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗 :14.1 MB, 在所有 C++ 提交中击败了24.42%的用户

代码

/**
 * 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>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        vector<int> curr_level;
        queue<TreeNode*> bfs_queue;
        bfs_queue.push(root);
        bfs_queue.push(NULL); // 标志本层的末尾
        while(!bfs_queue.empty()){
            TreeNode* curr_ptr = bfs_queue.front();
            bfs_queue.pop();
            if(curr_ptr == NULL){ // 如果某一层已经到末尾,则进行整理工作
                if(!curr_level.empty())
                    result.push_back(curr_level);
                curr_level.clear();
            }
            else{
                curr_level.push_back(curr_ptr -> val);
                if(curr_ptr -> left != NULL) bfs_queue.push(curr_ptr -> left);
                if(curr_ptr -> right != NULL) bfs_queue.push(curr_ptr -> right);
                if(bfs_queue.front() == NULL) bfs_queue.push(NULL); // 标志下一层的终结
            }
        }
        return result;
    }
};

正反交替层序遍历

103. Binary Tree Zigzag Level Order Traversal

Given the root of a binary tree, return the zigzag level order traversal of its nodes’ values. (i.e., from left to right, then right to left for the next level and alternate between).

Example 1:

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[20,9],[15,7]]

Example 2:

Input: root = [1]
Output: [[1]]

Example 3:

Input: root = []
Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 2000].
  • -100 <= Node.val <= 100

题解

在102题的基础上,每次result.push_back的时候判断一下是否要reverse就行了。执行用时0ms,内存消耗13.8MB.

代码

/**
 * 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>> result;
        vector<int> curr_level;
        queue<TreeNode*> bfs_queue;
        bfs_queue.push(root); // 第1层的内容是root和NULL
        bfs_queue.push(NULL); // NULL标志本层的末尾
        bool flag = true; // 决定从左向右还是从右向左
        while(!bfs_queue.empty()){
            TreeNode* curr_ptr = bfs_queue.front();
            bfs_queue.pop();
            if(curr_ptr == NULL){ // 如果某一层已经到末尾,则进行整理工作
                if(!curr_level.empty()){
                    // 在下面的逻辑中,会出现对最后一个空层之后的层打NULL标签的情况,此时这种空层不能输出
                    if(!flag) reverse(curr_level.begin(),curr_level.end());
                    flag = !flag;
                    result.push_back(curr_level);
                }
                curr_level.clear();
            }
            else{
                curr_level.push_back(curr_ptr -> val);
                if(curr_ptr -> left != NULL) bfs_queue.push(curr_ptr -> left);
                if(curr_ptr -> right != NULL) bfs_queue.push(curr_ptr -> right);
                if(bfs_queue.front() == NULL) bfs_queue.push(NULL); // 标志下一层的终结
            }
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值