• 微软面试题: LeetCode 103. 二叉树的锯齿形层次遍历 middle 出现次数:3


    题目描述:

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

    分析:

      本题考察的是二叉树的层次遍历思想。二叉树的层次遍历需要借助一个队列辅助 。算法框架如下:

     1 void levelOrderTraverse(TreeNode* root)
     2 {
     3     queue<TreeNode*> q;
     4     //初始状态,先将根节点入队
     5     q.push(root);
     6     while(!q.empty())
     7     {
     8         //取出队头的节点(最早入队的)访问(操作),并从队列中拿出
     9         TreeNode* node = q.top();
    10         visit(node);
    11         q.pop();
    12         //对出队节点的左右子节点入队列
    13         if(node->left) q.push(node->left);
    14         if(node->right) q.push(node->right);
    15     }
    16     //队空跳出 while loop,二叉树的所有元素已经访问完毕
    17     return ;
    18 }

     本题考查的是对上面标准二叉树层次遍历框架的使用!

      以root 节点为二叉树的第 1 层,对二叉树锯齿形层次遍历 就是对单层的节点从前往后,对双层的节点从后往前。

      初始状态:将根节点入队,队列中只有一个根节点,即队列中保存的是第一层的全部节点,队列的大小就是第一层节点的节点数。

    此时的层数 level = 1 ;

          每次遍历完某一层的所有节点并将其pop出队列的同时也将下一层的所有节点都 push 到队列中了 ;

      使用一个双端队列 deque ,在遍历处理某一层的所有节点时,如是奇数层 全都 push_back 到deque 中,若是偶数层 

    全都 push_front 到 deque 中。
         算法的时间复杂度是 O(n) 空间复杂度 O(n)
    具体看下面的代码和注释:
     1 /**
     2  * Definition for a binary tree node.
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     8  * };
     9  */
    10 
    11 class Solution {
    12 public:
    13 //二叉树的层次遍历
    14     vector<vector<int>> zigzagLevelOrder(TreeNode* root)
    15     {
    16         //特殊情况处理
    17         vector<vector<int>> res;
    18         if(root == NULL) return res;
    19         //二叉树层次遍历的辅助
    20         queue<TreeNode*> q;
    21         //状态初始化:层数为1 ,队列中有第一层的所有节点,
    22         q.push(root);
    23         int level = 1;//层数
    24         /*最外层循环:队列未空表示 队列中的节点还没有遍历处理到,且其可能的子节点(下一层节点),还未入队。
    25                     队列空了:二叉树所有节点都已经遍历处理 */
    26         while(!q.empty())
    27         {
    28            // vector<int> tmp_vec;
    29             deque<int> tmp_deq;//使用deque是因为 deque 的push_front 比 vector的insert更高效
    30             int q_len = q.size();//当前层的节点个数
    31             while(q_len--)//当前层节点都遍历完出栈后,下一层的节点也全部入栈了
    32             {
    33                 TreeNode* node = q.front();
    34                 q.pop();
    35                 if(level%2 == 0)//偶数层需要正序序列,直接插入deque尾部
    36                 {
    37                   //  tmp_vec.insert(tmp_vec.begin(),node->val);
    38                   tmp_deq.push_front(node->val); //deque 的push_front 比 vector的insert更高效
    39                 }
    40                 else  //奇数层需要逆序序列,头插法依次插入deque头部
    41                 {
    42                     //tmp_vec.push_back(node->val);
    43                     tmp_deq.push_back(node->val);
    44                 }
    45                 if(node->left)
    46                 {
    47                     q.push(node->left);
    48                 }
    49                 if(node->right)
    50                 {
    51                     q.push(node->right);
    52                 }
    53             }
    54             //将当前层的遍历结果 push_back 到 res
    55            // res.push_back(tmp_vec);
    56            res.push_back(vector<int>(tmp_deq.begin(), tmp_deq.end()));
    57            //遍历处理下一层节点
    58            ++level;
    59         }
    60         return res;
    61     }
    62 };
      

      

  • 相关阅读:
    android xml 布局错误
    java int与integer的区别
    android html.fromHtml 用例
    Android 手势操作识别
    android android 判断是否滑动
    Android 通过 Intent 传递类对象或list对象
    android 学习JSON
    android 解决ListView点击与滑动事件冲突
    关于android的日志输出&LogCat
    android ListView 属性
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/14022563.html
Copyright © 2020-2023  润新知