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