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

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

1.题目描述:

给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

例如:
给定二叉树 [3,9,20,null,null,15,7],
#输入的二叉树输出:
返回锯齿形层序遍历如下:
[[3],[20,9],[15,7]]

2.解题思路

问题是基于二叉树层次遍历的衍生遍历方法。关于二叉树的遍历方法,主要分为先序遍历、中序遍历、后序遍历以及层次遍历。
层次遍历,顾名思义就是按照二叉树的层次开始遍历,本题描述为锯齿形层次遍历,每一层的遍历方向都和上一层相反。我们利用队列来辅助进行层次遍历,通过变量deep来控制当前遍历层次的深度(deep从0开始计数)。deep是偶数的时候,从左往右遍历,根据队列先进先出(FIFO)的原则,将每次遍历的结果通过尾插法插入到 List 里,deep是奇数时,从右往左遍历,通过头插法(每次数据都插入到 index = 0 的位置)插入到List里。
另一个问题:
如何控制使得每次都刚好遍历一层。使用变量 vol (根结点,第0层的 vol为1)来存储每一层的容量。这样通过一个for循环就可以保证每次遍历都是一层。

代码逻辑
/* 初始化变量
 * // 层次遍历
 * while(队列非空){
 * 		// 遍历该层
 * 		// 方法:
 * 		// 取出队列信息
 * 		// 根据deep值选择头插或者尾插
 * 		// 将取出节点的叶子结点存入队列
 * 		// 更新vol、deep
 * }
 */
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if(root == null) { return ans; }
        int deep = 0;
        int vol = 1;    // 记录容量
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()){
            List<Integer> tmpTraMsg = new ArrayList<>();
            Queue<TreeNode> tmpQ = new LinkedList<>();
            int tmpVol = 0;
            // 将下一层的信息录入到q,更新下一层的vol,更新这一层的信息
            for(int i = 0; i < vol; i++){
                TreeNode tmpNode = q.remove();
                if(tmpNode.left != null){
                    q.add(tmpNode.left);
                    tmpVol++;
                }
                if(tmpNode.right != null){
                    q.add(tmpNode.right);
                    tmpVol++;
                }
                if(deep % 2 == 0){
                    // 正向遍历,尾插
                    tmpTraMsg.add(tmpNode.val);
                }else{
                    // 反向遍历,头插
                    tmpTraMsg.add(0,tmpNode.val);
                }
            }
            deep++;
            ans.add(tmpTraMsg);
            vol = tmpVol;
        }
        return ans;
    }
运行结果

运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值