lc_bfs_103_zigzagLevelOrder

19 篇文章 0 订阅
10 篇文章 0 订阅

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

package leetCode.BFS;

import java.util.*;

public class lc_bfs_103_zigzagLevelOrder {
/*
题目: 二叉树的锯齿形层次遍历 middle
  给定一个二叉树,返回其节点值的锯齿形层次遍历。
(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

例如:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回锯齿形层次遍历如下:

[
  [3],
  [20,9],
  [15,7]
]

*/

/*
思路:
1)官方方法:nodeQue的顺序不变,valQue处理顺序。使用一个双端队列LinkedList处理
2)我的方法:valQue的顺序不变,nodeQue处理顺序。使用两个栈ArrayDeque处理

*/


    /**
     * 我的方法:valQue的顺序不变,nodeQue处理顺序。leetCode执行效率不够好,但也是O(n)啊,很奇怪!
     * 使用两个stack,分别存放奇数层(odd)和偶数层(even)的结点
     * odd按左右的顺序,存放子节点到even;even按右左的顺序存放子节点到odd,交替执行。
     * level按顺序存放结点值就行。
     *
     * @param root
     * @return
     */
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ans = new LinkedList<>();
        if (root == null)
            return ans;
        Deque<TreeNode> oddNodeQue = new ArrayDeque<>();//存放奇数层结点
        Deque<TreeNode> evenNodeQue = new ArrayDeque<>();//存放偶数层结点
        oddNodeQue.push(root);
        while (!oddNodeQue.isEmpty() || !evenNodeQue.isEmpty()) {//本次while循环可以同时遍历一次odd和even
            List<Integer> valQueue = new LinkedList<>();
            while (!oddNodeQue.isEmpty()) {
                TreeNode node = oddNodeQue.pop();
                valQueue.add(node.val);
                if (node.left != null)//先左再右
                    evenNodeQue.push(node.left);
                if (node.right != null)
                    evenNodeQue.push(node.right);
            }
            ans.add(new LinkedList<>(valQueue));
            valQueue = new LinkedList<>();//在处理even前清空level队列
            while (!evenNodeQue.isEmpty()) {
                TreeNode node = evenNodeQue.pop();
                valQueue.add(node.val);
                if (node.right != null)//先右再左
                    oddNodeQue.push(node.right);
                if (node.left != null)
                    oddNodeQue.push(node.left);
            }
            if (valQueue.size() != 0)//最后一层是奇数层时,如果不加判断会加入空level
                ans.add(new LinkedList<>(valQueue));
        }
        return ans;
    }

    /**
     * 官方的方法:nodeQue的顺序不变,valQue处理顺序。O(n),执行效率更好,不懂为啥
     * 和经典的层序遍历差不多。
     * 存放node时都按照左右顺序存放
     * 关键是使用双端队列的addLast和addFirst方法
     * 在添加值到valQue时,用left_order判断valQue是否需要逆序存放,该层遍历完left_order取反
     *
     * @param root
     * @return
     */
    public List<List<Integer>> zigzagLevelOrder2(TreeNode root) {
        List<List<Integer>> ans = new LinkedList<>();
        if (root == null)
            return ans;
        LinkedList<TreeNode> nodeQue = new LinkedList<>();
        nodeQue.add(root);
        boolean left_order = true;//用left_order判断valQue是否需要逆序存放
        LinkedList<Integer> valQue = new LinkedList<>();
        int count = 0;
        while (!nodeQue.isEmpty()) {
            count = nodeQue.size();//该层要遍历的结点数
            while (count > 0) {
                TreeNode cur = nodeQue.poll();
                if (left_order)//判断是否要逆序存放到valQue
                    valQue.addLast(cur.val);
                else
                    valQue.addFirst(cur.val);
                if (cur.left != null)
                    nodeQue.add(cur.left);
                if (cur.right != null)
                    nodeQue.add(cur.right);
                count--;
            }
            ans.add(valQue);
            valQue = new LinkedList<>();//清空
            left_order = !left_order;//该层遍历完取反

        }
        return ans;
    }


    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值