二叉树的分层遍历、栈的压入弹出序列

        本章主要来讲解两个OJ题,针对每个OJ题我分三部分来解决,分别是题目解析(主要弄清楚题目要求我们解决什么问题),算法原理,代码编写,接下来让我们进入正题。

一、二叉树的分层遍历

1.题目解析

        题目的要求层序遍历,并且要将数据分层存储到数组中,所以需要一个二维数组作为返回值,而该题并不是简单的层序遍历,重难点在于如何把这些数据分层地存储到二维数组中,如何区分他们哪层是哪层?接下来看算法原理。

2.算法原理

        对于层序遍历(广度优先遍历)使用队列再合适不过了,首先把根节点放入队列中,然后出队,访问它的左右子节点并依次放入队列中,循环进行以上操作直到队列为空,这样就能够完成层序优先遍历,不过还有一个要点就是如何把数据分层存入二维数组中。

        要分层存储数据首先就需要分清楚数据分别在哪层,那么我们可以用一个变量来记录每层数据的个数,用while来单独处理每一层,比如示例一,第一层的数据个数是1个,那么用一个循环(循环的次数即为该层数据的个数)处理完第一层的数据,然后队列里的数据个数(2个)即为第二层的数据个数,然后使用循环(循环的次数即为该层数据的个数)处理第二层的数据,以此类推,直到队列为空。

3.代码编写

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> qu;
        vector<vector<int>> arr;
        if(root)
            qu.push(root);
        while(!qu.empty())
        {
            int sum=qu.size();//记录每层数据个数
            vector<int> ar;
            ar.reserve(sum);//提前开好空间减少扩容次数,提高效率
            while(sum--)
            {
                TreeNode* rt=qu.front();
                ar.push_back(rt->val);
                qu.pop();
                if(rt->left)
                    qu.push(rt->left);
                if(rt->right)
                    qu.push(rt->right);
            }
            arr.push_back(ar);
        }
        return arr;
    }
};

二、栈的压入弹出序列

1.题目解析

题目意思是给一个压栈顺序,一个出栈序列,要求判断该压栈顺序能不能弹出这样出栈序列。                例如示例一:压栈顺序1 2 3 4 5,出栈顺序4 3 5 2 1,为了达到这种出站栈顺序可以是1 2 3 4 入栈,4出栈,3出栈,5入栈,5出栈,2出栈,1出栈。即push(1),push(2),push(3),push(4),pop(4),pop(3),push(5),pop(5),pop(2),pop(1)。

        示例二:压栈顺序1 2 3 4 5,出栈顺序4 3 5 1 2,为了达到这种出站栈顺序可以是1 2 3 4 入栈,4出栈,3出栈,5入栈,5出栈,然后只能是1出栈,2出栈,并不能模拟出所给的出栈效果,所以返回false。

2.算法原理

        通过上面的解析我们发现,只要随便给一组入栈出栈序列,我们可以根据栈的存储规则自行判断出是否匹配。判断方法就是模拟栈的存取过程,那么我们的算法设计可以模拟栈操作,就是把我们的判断方法用代码模拟一遍。

        模拟方法:准备一个空栈,准备两个指针p1和p2分别指向入栈和出栈序列的首元素下标。

        第一步:把p1指向数据入栈,p1后移。

        第二步:判断栈顶元素与p2指向元素是否相等,若相等则栈顶元素出栈,p2后移,然后再次判断栈顶元素与p2指向元素是否相等,以此方式重复进行直到不相等为止,进入第三部。

        第三部:重复第一步和第二部,直到p1移动到数组末尾,然后判断栈是否为空,若为空说明数据都匹配上了返回true,若不是则返回false。

3.代码编写

bool IsPopOrder(vector<int>& pushV, vector<int>& popV) 
{
    stack<int> stk;
    int p1=0,p2=0;
    while(p1<pushV.size())
    {
        stk.push(pushV[p1++]);
        while(!stk.empty()&&stk.top()==popV[p2])
        {
            stk.pop();
            p2++;
        }
    }
    return stk.empty();
}
评论 82
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值