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}
,java
3 / \ 9 20 / \ 15 7
return its zigzag level order traversal as:node
[ [3], [20,9], [15,7] ]
给定一棵二叉树,从顶向下,进行Z字形分层遍历,即:若是本层是从左向右的,下层就是从右向左。算法
二叉树分层遍历进行改进,使用两个栈来进行。spa
树结点类.net
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
算法实现类code
import java.util.Deque; import java.util.LinkedList; import java.util.List; public class Solution { public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> result = new LinkedList<>(); if (root == null) { return result; } // 遍历标志,0表示从左到右,1表示从右到左 int flag = 0; TreeNode node; // 记录每一层的元素 List<Integer> lay = new LinkedList<>(); // 双向队列,看成栈来使用,记录当前层待处理结点 Deque<TreeNode> stack = new LinkedList<>(); // 记录下一层待处理结点 Deque<TreeNode> nextStack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { // 删除栈顶元素 node = stack.removeLast(); // 结果入队 lay.add(node.val); // 若是当前是从左到右遍历,按左子树右子树的顺序添加 if (flag == 0) { if (node.left != null) { nextStack.addLast(node.left); } if (node.right != null) { nextStack.addLast(node.right); } } // 若是当前是从右到左遍历,按右子树左子树的顺序添加 else { if (node.right != null) { nextStack.addLast(node.right); } if (node.left != null) { nextStack.addLast(node.left); } } // 当前层已经处理完了 if (stack.isEmpty()) { Deque<TreeNode> temp = nextStack; nextStack = stack; stack = temp; // 标记下一层处理的方向 flag = 1 - flag; // 保存本层结果 result.add(lay); // 建立新的链表处理下一层的结果 lay = new LinkedList<>(); } } return result; } }
解题思路:
这题和第102题解法相似,对102题的方法进行改造,使用两个Deque来实现,第一个Deque()实现本层的遍历,第二个Deque()实现下层节点的输入。队列
二,AC了的程序(采用Java程序)图片
import java.util.*; class TreeNode{ int val; TreeNode left; TreeNode right; TreeNode(int x) { val=x; } } public class Test2 { List<List<Integer>> list=new ArrayList<List<Integer>>(); //leetcode 103 public List<List<Integer>> zigzagLevelOrder(TreeNode root) { if(root==null) { return list; } //LinkedList<TreeNode> queue=new LinkedList<TreeNode>(); //定义LinkedList类型 //queue.offer(root); // 首先把根节点入队列 boolean temp1=false; //temp1=false表示从左到右遍历,temp2=true表示从右到左遍历 Deque<TreeNode> queue=new LinkedList<TreeNode>();//Deque是双向队列,双向队列是指该队列两端的元素既可以入队,也能出队 Deque<TreeNode> nextqueue=new LinkedList<TreeNode>(); //记录下一层待处理结点 queue.add(root); //首先先把二叉树的根进入双端队列 List<Integer> templist=new LinkedList<Integer>(); //templist为临时的集; while(!queue.isEmpty()) //该双端队列不为空的 { TreeNode node=queue.removeLast();//删除 templist.add(node.val); //把节点值加入到临时集 if(temp1==false) //若是当前是从左到右遍历的,那么下一层要从左到右添加节点 { if(node.left!=null) { nextqueue.addLast(node.left); } if(node.right!=null) { nextqueue.addLast(node.right); } } else //当前是从右到左遍历的,那么下层就要从右到左添加节点的。 { if(node.right!=null) { nextqueue.addLast(node.right); } if(node.left!=null) { nextqueue.addLast(node.left); } } if(queue.isEmpty()) //若是当前这层已经变为空了 { Deque<TreeNode> temp=nextqueue; //就把下一层节点复制给当前节点,下一层的Deque边为空的 nextqueue=queue; //下一层deque变为空的。 queue=temp; temp1=(temp1==false)?true:false; list.add(templist); templist=new LinkedList<Integer>(); } } return list; } public static void main(String []args) { Test2 test=new Test2(); TreeNode root=new TreeNode(3); TreeNode p2=new TreeNode(9); TreeNode p3=new TreeNode(20); TreeNode p4=new TreeNode(15); TreeNode p5=new TreeNode(7); TreeNode p6=new TreeNode(4); TreeNode p7=new TreeNode(5); root.left=p2; root.right=p3; p3.left=p4; p3.right=p5; p5.left=p6; p5.right=p7; /* TreeNode root=new TreeNode(1); TreeNode p2=new TreeNode(2); TreeNode p3=new TreeNode(3); TreeNode p4=new TreeNode(4); TreeNode p5=new TreeNode(5); root.left=p2; root.right=p3; p2.left=p4; p3.right=p5; */ List<List<Integer>> list=test.zigzagLevelOrder(root); Iterator<List<Integer>> it1=list.iterator(); while(it1.hasNext()) { List<Integer> list2=it1.next(); Iterator<Integer> it2=list2.iterator(); while(it2.hasNext()) { int data=it2.next(); System.out.print(data+" "); } System.out.println(); } } }
运行结果:
leetcode