两个leetcode题

1.二叉树的层序遍历

leetcode原题

方法一:广度优先搜索
    // 定义一个名为Solution的类  
    class Solution {  
    public:  
    // 定义一个公共方法levelOrder,接受一个二叉树的根节点指针作为参数,返回一个二维向量  
    vector> levelOrder(TreeNode* root) {  
        // 初始化一个空的二维向量ret,用于存储层序遍历的结果  
        vector> ret;  
        // 如果根节点为空,直接返回空的二维向量  
        if (!root) {  
            return ret;  
        }  
     // 创建一个队列q,用于层序遍历中的广度优先搜索  
    queue<TreeNode*> q;  
    // 将根节点推入队列  
    q.push(root);  

    // 当队列不为空时,循环进行层序遍历  
    while (!q.empty()) {  
        // 获取当前层的节点数量(即队列的大小)  
        int currentLevelSize = q.size();  
        // 在ret中添加一个新的空向量,用于存储当前层的节点值  
        ret.push_back(vector<int>());  

        // 循环处理当前层的每个节点  
        for (int i = 1; i <= currentLevelSize; ++i) {  
            // 取出队列的前端节点,并将其从队列中移除  
            auto node = q.front();   
            q.pop();  
            // 将当前节点的值添加到ret的当前层向量中  
            ret.back().push_back(node->val);  
            // 如果当前节点有左子节点,则将左子节点推入队列  
            if (node->left) q.push(node->left);  
            // 如果当前节点有右子节点,则将右子节点推入队列  
            if (node->right) q.push(node->right);  
        }  
    }  
      
    // 返回层序遍历的结果  
    return ret;  
}  

};

核心问题:

在层序遍历的过程中,我们使用队列q来按照广度优先的顺序存储和访问二叉树的节点。当我们调用q.front()来获取队列前面的节点时,这个节点属于当前层级的节点,而不是下一层级的节点。但是,当我们把这个节点从队列中移除(通过q.pop())并处理它的子节点时,我们会把这些子节点(如果存在的话)压入队列中。

现在,让我们解释一下为什么在处理完当前层级的节点后,q.size()表示的是下一层级的节点数量。

当我们开始处理当前层级的节点时,队列中存储的是下一层级的节点。因此,q.size()在开始处理当前层级时表示的是下一层级的节点数量。

当我们处理当前层级的节点时,我们会把这些节点从队列中移除,并处理它们的子节点。如果我们把当前层级的所有节点都处理完了,那么队列中剩下的就是下一层级的节点。 因此,在处理完当前层级的所有节点后,q.size()表示的是下一层级的节点数量。这是因为我们已经把当前层级的所有节点从队列中移除了,而它们的子节点(即下一层级的节点)被压入了队列中。

总的来说,q.size()之所以在处理完当前层级后表示下一层级的节点数量,是因为我们使用队列来进行广度优先搜索,按照层级顺序处理节点,并在处理完当前层级的节点后将其从队列中移除,并将下一层级的节点压入队列中。因此,q.size()反映的是队列中剩余节点的数量,也就是下一层级的节点数量。

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

leetcode原题

方法一:广度优先遍历
    // 定义一个Solution类,用于存储二叉树的锯齿形层次遍历解决方案  
    class Solution {  
    public:  
    // 定义一个二维向量,用于存储每一层的节点值  
    vector> zigzagLevelOrder(TreeNode* root) {  
        // 初始化结果向量  
        vector> ans; 
    // 如果根节点为空,则直接返回空的结果向量  
    if (!root) {  
        return ans;  
    }  
    // 创建一个队列,用于存储待处理的节点  
    queue<TreeNode*> nodeQueue;  
    // 将根节点加入队列  
    nodeQueue.push(root);  
    // 定义一个布尔变量,用于决定遍历顺序,初始值为true,表示从左到右  
    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();  
            // 如果isOrderLeft为true,则从左到右添加节点值到levelList中  
            if (isOrderLeft) {  
                levelList.push_back(node->val);  
            } else {  
                // 否则,从右到左添加节点值到levelList中  
                levelList.push_front(node->val);  
            }  
            // 如果当前节点有左子节点,则将其加入队列中,以便下一层处理  
            if (node->left) {  
                nodeQueue.push(node->left);  
            }  
            // 如果当前节点有右子节点,则将其加入队列中,以便下一层处理  
            if (node->right) {  
                nodeQueue.push(node->right);  
            }  
        }  
        // 将当前层的levelList添加到结果向量ans中  
        ans.emplace_back(vector<int>{levelList.begin(), levelList.end()});  
        // 切换isOrderLeft的值,以便下一层使用相反的遍历顺序  
        isOrderLeft = !isOrderLeft;  
    }  
    // 返回结果向量ans  
    return ans;  
}  

};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值