Leetcode 103.二叉树的之字形遍历:双端队列与广度优先搜索

要求以之字形遍历一个二叉树的每一层,并将结果储存在一个List当中。
例:
Leetcode 103.二叉树的之字形遍历:双端队列与广度优先搜索_第1张图片
输出结果:
[ [ 4 ] , [ 3 , 2 ] , [ 1 , 8 , 7 ] , [ 10 ] ] [[4],[3,2],[1,8,7],[10]] [[4],[3,2],[1,8,7],[10]]

思路:采用广度优先搜索,用一个双端队列(Deque)遍历节点。为了实现之字形遍历,每当进入下一层,改从另一头进出即可。

public List<List<Integer>> zigzag(TreeNode root) {

        //储存结果的List
        List<List<Integer>> list = new ArrayList<>();
        if (root == null) {
            return list;
        }

        //初始化用于遍历二叉树的Deque,将根节点入列,设定初始层数为1
        Deque<TreeNode> nodeDeque = new ArrayDeque<>();
        nodeDeque.addFirst(root);
        int L = 1;
        
        //每次循环遍历二叉树的一层,并将下一层的节点储存进列
        while (!nodeDeque.isEmpty()) {
        
            //获取目前要遍历的这一层的节点数
            int size = nodeDeque.size();
            list.add(new ArrayList<>());

            //奇数层的节点在头部进出列
            for (int i = 0; L % 2 > 0 && i < size; i++) {
                TreeNode node = nodeDeque.pollFirst();
                list.get(list.size() - 1).add(node.val);

                //将下一层的非空左节点和右节点在尾部入列
                if (node.left != null) {
                    nodeDeque.addLast(node.left);
                }
                if (node.right != null) {
                    nodeDeque.addLast(node.right);
                }
            }

            //偶数层的节点在尾部进出列
            for (int i = 0; L % 2 == 0 && i < size; i++) {
                TreeNode node = nodeDeque.pollLast();
                list.get(list.size() - 1).add(node.val);

                //将下一层的右节点和左节点在头部入列
                if (node.right != null) {
                    nodeDeque.addFirst(node.right);
                }
                if (node.left != null) {
                    nodeDeque.addFirst(node.left);
                }
            }

            //增加层数
            L++;
        }
        return list;
    }

思考:

容易想到要用广度优先搜索(BFS)来遍历每一层,但之字形遍历使得每一层的移动方向会发生变化。单独使用栈或队列的数据结构都无法满足这一要求,因此需要灵活运用双端队列的特性,实现奇数层在头部进出,偶数层在尾部进出。

你可能感兴趣的:(Java,算法)