103 Binary Tree Zigzag Level Order Traversal

题目链接:https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/

题目:

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,#,#,15,7},
    3
   / \
  9  20
    /  \
   15   7
return its zigzag level order traversal as:
[
  [3],
  [20,9],
  [15,7]
]
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.


OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".

解题思路:

  1. 层次遍历二叉树(入队列的形式),在队列中,行和行之间以一个值为最小整数(Integer.MIN_VALUE)的节点隔开
  2. 偶数行出队列时,按顺序加入到子链表中;奇数行出队列时,按逆序(头插法)加入到子链表中。root 节点在第0行。
  3. 每遍历完一行,就将子链表加入到输出的链表中。

注意:
LinkedList 类实现了, Deque, List, Queue接口,因而,可以头插(addFirst()),可以尾插(add())。因而某种程度上,链表可以是队列,也可以是栈!!!

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> list = new LinkedList();
        if(root == null)
            return list;
        LinkedList<TreeNode> queue = new LinkedList();
        int i = 0;
        queue.add(root);
        TreeNode temp = new TreeNode(Integer.MIN_VALUE);
        queue.add(temp);
        LinkedList<Integer> subList = null;
        while(!queue.isEmpty() ) {
            TreeNode node = queue.peek();
            queue.remove();
            if(node.val == Integer.MIN_VALUE) {
                list.add(subList);
                if(queue.isEmpty())
                    break;
                else {
                    subList = new LinkedList();
                    queue.add(temp);
                    i ++;
                    continue;
                }
            }
            if(i == 0)
                subList = new LinkedList();
            if(i % 2 == 0)
                subList.add(node.val);
            else
                subList.addFirst(node.val);
            System.out.println(subList.size());
            if(node.left != null)
                queue.add(node.left);
            if(node.right != null)
                queue.add(node.right);
        }
        return list;
    }
}
33 / 33 test cases passed.
Status: Accepted
Runtime: 380 ms

上面的算法,速度不够快。

方法二:
参考链接:http://blog.csdn.net/linhuanmars/article/details/24509105

解题思路:
这道题其实还是树的层序遍历Binary Tree Level Order Traversal,如果不熟悉的朋友可以先看看哈。不过这里稍微做了一点变体,就是在遍历的时候偶数层自左向右,而奇数层自右向左。在Binary Tree Level Order Traversal中我们是维护了一个队列来完成遍历,而在这里为了使每次都倒序出来,我们很容易想到用栈的结构来完成这个操作。有一个区别是这里我们需要一层一层的来处理(原来可以按队列插入就可以,因为后进来的元素不会先处理),所以会同时维护新旧两个栈,一个来读取,一个存储下一层结点。总体来说还是一次遍历完成,所以时间复杂度是O(n),空间复杂度最坏是两层的结点,所以数量级还是O(n)(满二叉树最后一层的结点是n/2个)。

维护两个栈,一个新栈,一个旧栈。新栈用于存放当前层的节点(实现入栈),旧栈存放上一层的节点(实现出栈)。用 LinkedList 实现栈。还维护一个 ArrayList 用于存放当前层的元素值,即当前行元素值子链表。偶数层,将子节点从左到右入栈;奇数层,将子节点从右到左入栈。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {  
        List<List<Integer>> res = new ArrayList();  
        if(root==null)  
            return res;  
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();  
        int level=1;  
        List<Integer> item = new ArrayList<Integer>();  
        item.add(root.val);  
        res.add(item);  
        stack.push(root);  
        while(!stack.isEmpty())  
        {  
            LinkedList<TreeNode> newStack = new LinkedList<TreeNode>();  
            item = new ArrayList<Integer>();  
            while(!stack.isEmpty())  
            {  
                TreeNode node = stack.pop();  
                if(level%2==0)  
                {  
                    if(node.left!=null)  
                    {  
                        newStack.push(node.left);  
                        item.add(node.left.val);  
                    }  
                    if(node.right!=null)  
                    {  
                        newStack.push(node.right);  
                        item.add(node.right.val);  
                    }  
                }  
                else  
                {  
                    if(node.right!=null)  
                    {  
                        newStack.push(node.right);  
                        item.add(node.right.val);  
                    }  
                    if(node.left!=null)  
                    {  
                        newStack.push(node.left);  
                        item.add(node.left.val);  
                    }                     
                }  
            }  
            level++;  
            if(item.size()>0)  
                res.add(item);  
            stack = newStack;  
        }  
        return res;  
    }  
}
33 / 33 test cases passed.
Status: Accepted
Runtime: 308 ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值