leetcode 199 从右看二叉树
面试的时候不会写,只写完了层次遍历,挂了,Orz。
思路:
1.层次遍历,bfs。
2.遇到新层的第一个节点才会添加新层。
3.每层从右往左遍历,则最右的始终是每层的第一个。
4.结合2,3。当需要添加新层时,将节点值添加进结果集。
用到的数据结构:
1.队列,这里用双向Deque。
2.线性表,存结果。
3.Map,记录节点对应的level。
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 class Solution { 11 public List<Integer> rightSideView(TreeNode root) { 12 Deque<TreeNode> dq = new ArrayDeque<TreeNode>(); 13 List<Integer> ans = new ArrayList<Integer>(); 14 Map<TreeNode, Integer> level = new HashMap<TreeNode, Integer>(); 15 if (root != null){ 16 dq.addLast(root); 17 level.put(root, 1); 18 ans.add(root.val); 19 } 20 while (!dq.isEmpty()) { 21 TreeNode top = dq.getFirst(); 22 dq.removeFirst(); 23 if (top.right != null) { 24 dq.addLast(top.right); 25 level.put(top.right, level.get(top) + 1); 26 if (ans.size() < level.get(top) + 1) { 27 ans.add(top.right.val); 28 } 29 } 30 if (top.left != null) { 31 dq.addLast(top.left); 32 level.put(top.left, level.get(top) + 1); 33 if (ans.size() < level.get(top) + 1) { 34 ans.add(top.left.val); 35 } 36 } 37 } 38 return ans; 39 } 40 }
4月5日更新。
一种效率更高,更简洁的版本。
这种写法确保每次while结束后队列里的元素永远是下一层的所有结点(或者没有结点)。
学习到了,原来用一个内置的for循环就能完成。
1 class Solution { 2 public List<Integer> rightSideView(TreeNode root) { 3 List<Integer> ans = new ArrayList<>(); 4 if (root == null) 5 return ans; 6 Deque<TreeNode> dq = new ArrayDeque<>(); 7 dq.addLast(root); 8 while (!dq.isEmpty()) { 9 //从根所在的level逐层更新 10 int num = dq.size(); 11 for (int i = 0; i < num; i++) { 12 TreeNode tmp = dq.getFirst(); 13 if (tmp.left != null) 14 dq.addLast(tmp.left); 15 if (tmp.right != null) 16 dq.addLast(tmp.right); 17 if (i == num - 1) 18 ans.add(tmp.val); 19 dq.removeFirst(); 20 } 21 } 22 return ans; 23 } 24 }