Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

LeetCode 103. Binary Tree Zigzag Level Order Traversal

Woodyiiiiiii opened this issue · comments

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:

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

题目要求按照Zigzag格式存放二叉树节点值,第一行从左至右,第二行从右至左,第三行再从左至右...如此顺序。

我的第一个反应是按照102. Binary Tree Level Order Traversal的思路设置两个节点判断是否为一行的思路,层次遍历二叉树。代码如下:

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> lists = new LinkedList();
        if (root == null) return lists;
        TreeNode flag1 = root, flag2 = null, node = null;
        int order = 1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        List<Integer> list = new LinkedList<>();
        while (!queue.isEmpty()) {
            node = queue.poll();
            flag2 = (node.right != null ) ? node.right 
                : (node.left != null ? node.left : flag2);
            list.add(node.val);
            if (node == flag1) {
                if (order == 1) {
                    lists.add(list);
                    order = 0;
                }else {
                    List<Integer> tmp = new LinkedList<>();
                    for (int i = list.size() - 1; i >= 0; --i) {
                        tmp.add(list.get(i));
                    }
                    lists.add(tmp);
                    order = 1;
                }
                list = new LinkedList<>();
                flag1 = flag2;
            }
            if (node.left != null) queue.add(node.left);
            if (node.right != null) queue.add(node.right);
        }
        return lists;
    }
}

还有另一种做法,充分利用Java集合的LinkedList类作为双端队列的优势,即可以头尾插入或者删除元素的特点,可以设置以下添加二叉树节点方式:如果当前行是从左至右顺序的,从队头取出节点,并把该节点的左子节点和右子节点(如果存在)插入队尾中;如果当前行是从右至左顺序的,从队尾取出节点,并把该节点的右子节点和左子节点(如果存在)插入队头中。辨别是否到一行的结尾节点方法是分别设置last和nLast节点,last指向当前行尾节点,nLast是根据每行按照Zigzag顺序的头节点的左(或右)子节点来确立的。

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> lists = new LinkedList();
        if (root == null) return lists;
        TreeNode last = root, nLast = null, node = null;
        boolean lr = true;
        Deque<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        List<Integer> list = new LinkedList<>();
        while (!queue.isEmpty()) {
            if (lr) {
                node = queue.pollFirst();
                list.add(node.val);
                if (node.left != null) {
                    queue.offerLast(node.left);
                    nLast = (nLast == null) ? node.left : nLast;
                }
                if (node.right != null) {
                    queue.offerLast(node.right);
                    nLast = (nLast == null) ? node.right : nLast;
                }
            }else {
                node = queue.pollLast();
                list.add(node.val);
                if (node.right != null) {
                    queue.offerFirst(node.right);
                    nLast = (nLast == null) ? node.right : nLast;
                }
                if (node.left != null) {
                    queue.offerFirst(node.left);
                    nLast = (nLast == null) ? node.left : nLast;
                }
            }
            if (node == last) {
                lists.add(list);
                list = new LinkedList<>();
                last = nLast;
                nLast = null;
                lr = !lr;
            }
        }
        return lists;
    }
}

参考资料