【leetcode-102,107,103】 二叉树的层次遍历
102. 二叉树的层次遍历
(1过,隐蔽错误花时间很多,简单题目本应很快,下次注意红色错误的地方)
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回其层次遍历结果:
[ [3], [9,20], [15,7] ]
public static ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); if (root == null) { return res; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while(queue.size() > 0) { ArrayList<Integer> list = new ArrayList<>(); int size = queue.size(); // 之前写成了for (int i=0;i<queue.size();i++),而for循环内会让queue的size变化,很隐蔽的错误。应该先把size固定下来 for (int i=0;i<size;i++) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } res.add(list); } return res; }
107. 二叉树的层次遍历 II
(1过,就是一个列表反转,没练习意义)
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回其自底向上的层次遍历为:
[ [15,7], [9,20], [3] ]
public ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root) { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); if (root == null) { return res; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while(queue.size() > 0) { ArrayList<Integer> list = new ArrayList<>(); int size = queue.size(); // 之前写成了for (int i=0;i<queue.size();i++),而for循环内会让queue的size变化,很隐蔽的错误。应该先把size固定下来 for (int i=0;i<size;i++) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } res.add(list); } return reverse(res); } public ArrayList<ArrayList<Integer>> reverse(ArrayList<ArrayList<Integer>> list) { for (int i=0;i<list.size()/2;i++) { ArrayList<Integer> temp = list.get(i); list.set(i,list.get(list.size()-1-i)); list.set(list.size()-1-i,temp); } return list; }
103. 二叉树的锯齿形层次遍历
给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回锯齿形层次遍历如下:
[ [3], [20,9], [15,7] ]
这种变化也简单,下面参考代码的优点:
1.list.add(0, node.val)方法,list头部插入
2.栈的思想
链接:https://www.nowcoder.com/questionTerminal/47e1687126fa461e8a3aff8632aa5559
来源:牛客网
/** * * @author Jacob * 103. Binary Tree Zigzag Level Order Traversal * * 两种解法:1.使用两个堆栈;2.使用一个queue,用flag记录当前行打印顺序 */ public class Demo2 { /* * 方法一 解法与Binary Tree Level Order Traversal一致 区别是需要用一个flag判断应该正序or逆序打印 */ public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<List<Integer>>(); if (root == null) return res; Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.offer(root); // 用flag控制正序或者逆序打印 boolean flag = true; while (!queue.isEmpty()) { int size = queue.size(); ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); if (flag) list.add(node.val); else list.add(0, node.val); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); } flag = !flag; res.add(list); } return res; } /* * 解法二 使用两个堆栈 */ public List<List<Integer>> zigzagLevelOrder_2(TreeNode root) { TreeNode c = root; List<List<Integer>> ans = new ArrayList<List<Integer>>(); if (c == null) return ans; Stack<TreeNode> s1 = new Stack<TreeNode>(); Stack<TreeNode> s2 = new Stack<TreeNode>(); s1.push(root); while (!s1.isEmpty() || !s2.isEmpty()) { List<Integer> tmp = new ArrayList<Integer>(); while (!s1.isEmpty()) { c = s1.pop(); tmp.add(c.val); if (c.left != null) s2.push(c.left); if (c.right != null) s2.push(c.right); } ans.add(tmp); tmp = new ArrayList<Integer>(); while (!s2.isEmpty()) { c = s2.pop(); tmp.add(c.val); if (c.right != null) s1.push(c.right); if (c.left != null) s1.push(c.left); } if (!tmp.isEmpty()) ans.add(tmp); } return ans; } private class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } }