LeetCode103——zigzagLevelOrder of binary tree

这道题做的是二叉树的之字形遍历,之字形遍历本质就是层序遍历的变式问题,题面如下:
在这里插入图片描述
这道题和LeetCode102题同宗同源,不过难度更大一些,就以这道题为例将问题做一个总结。首先补充一点,查看示例代码可以发现期望返回的结果类型是vector嵌套另一个vector,也就是说答案希望将一个层次中的结点全部放在一个内层vector里,再保存到一个更大的外层vector中表示全部遍历的结果。这需要我们做一些处理,也就是我们得知道各个层次之间结点的界限,不能出现将一层的结点放到上一层或下一层的情况,否则内层的vector保存的结点就不对了,这点在本题中也有体现。

普通层次遍历(或者更广泛的说,广度优先搜索)使用的都是单端队列queue,之字形遍历需要的则是可以双端访问数据的双端队列deque,deque在C++ STL中被实现为一个容器适配器,这是题外之话。总而言之,支持这个算法所需要的基础数据结构是可以直接使用的。

思路很简单,我的想法是设置一个标记位来标定取元素的方向

/*Order is the sequence of traverse, 0 ->, 1 <-*/
bool Order = 0;

为了达成这样的效果,最好保证双端队列中的元素依旧按照从左到右,从上至下的层序遍历的日常顺序来存储,而只在具体取结点的时候反复的在双端队列的两端下手即可,这一点需要在存储下一层级子结点的顺序上做额外处理来保证其顺序,对于这点,我的实现代码是这样的:

if(Order == 0)
{
    
    
	...
    /*push the next layer's nodes into Q*/
    if(Front->left)
       Q.push_back(Front->left);
    if(Front->right)
       Q.push_back(Front->right);
}
/*using pop_back for present layer, push_front for sub nodes*/
else
{
    
    
     ...
     if(Back->right)
        Q.push_front(Back->right);
     if(Back->left)
        Q.push_front(Back->left);
}

最后一点就是用于首尾呼应的那个问题,如何区分不同层次结点之间的界限。这道题也就是《LeetCode102题:二叉树的层次遍历》的最重要的一点,就是遍历之前要先取队列的长度(也就是当前层次结点长度),以长度为界就不会出现结点读多或者读少的问题。

/*get the numeber of nodes in present layer*/
LayerLength = Q.size();

/*push a null vector to the end of Result*/
Result.push_back(vector<int>());

for(int i = 0 ; i < LayerLength ; ++i)
{
    
    
	...
}

下面给出完整代码,这就是解答本题时我的完整思路,在此做个记录。

 vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
    
    
        /*recursion result*/
        vector<vector<int>> Result;

        /*avoid special condition*/
        if(root == nullptr)
            return Result;
        
        /*layerlength is the number of nodes in a layer*/
        /*Order is the sequence of traverse, 0 ->, 1 <-*/
        int LayerLength;
        bool Order = 0;

        /*declare a deque here*/
        deque<TreeNode*> Q;

        /*push the root node in queue*/
        Q.push_back(root);

        while(!Q.empty())
        {
    
    
            /*get the numeber of nodes in present layer*/
            LayerLength = Q.size();

            /*push a null vector to the end of Result*/
            Result.push_back(vector<int>());

            for(int i = 0 ; i < LayerLength ; ++i)
            {
    
       
                /*using pop_front for present layer, push_back for sub nodes*/
                if(Order == 0)
                {
    
    
                    TreeNode* Front = Q.front();
                    Q.pop_front();
                    Result.back().push_back(Front->val);

                    /*push the next layer's nodes into Q*/
                    if(Front->left)
                        Q.push_back(Front->left);
                    if(Front->right)
                        Q.push_back(Front->right);
                }
                /*using pop_back for present layer, push_front for sub nodes*/
                else
                {
    
    
                    TreeNode* Back = Q.back();
                    Q.pop_back();
                    Result.back().push_back(Back->val);
                    if(Back->right)
                        Q.push_front(Back->right);
                    if(Back->left)
                        Q.push_front(Back->left);
                }
            }

            /*modify the sequence of next traverse*/
            if(Order)
                Order = 0;
            else
                Order = 1;
        }
        return Result;
    }

Guess you like

Origin blog.csdn.net/zzy980511/article/details/118931238