leetcode 二叉树的层序遍历整理以及java实现
二叉树的层序遍历再Leetcode里面有四道题是比较有代表性的,分别是:
- Binary Tree level order traversal
- Binary Tree level order traversal II
- Binary Tree zigzag level order traversal
- Binary Tree Vertical order Traversal
今天我们就分别看看这四道题的解析和java实现
Binary Tree level order traversal
这一题其实就是让我我们把每一层的节点的值放到一个数组里面,然后最后返回一个二维数组。一般来说涉及层级遍历的都可以用宽度优先搜索(BFS)来解决。让我们看看java的实现
class solution{
public List<List<Integer>> levelOrder(TreeNode root){
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
//这里一定要记得要把queue的当前大小保存到一个值中,不然是无法知道当前的层级拥有多少的节点的
int size = queue.size();
for(int i = 0 ; i < size(); i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
res.add(level);
}
return res;
}
}
这就是非常简单的一道BFS可以解决的问题。
Binary Tree Level order traversal II
这一题其实和第一题几乎是一样的,但是返回的顺序得是自下而上的,这种需要逆转顺序的其实我们都可以联想到用stack来实现。
class solution{
public List<List<Integer>> levelOrder(TreeNode root){
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Stack<List<Integer>> stack = new Stack<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
stack.push(level);
}
while(!stack.isEmpty()){
res.add(stack.pop());
}
return res;
}
}
其实就是多用stack结构反转了一遍。
Binary tree zigzag level traversal
这一题相比起一般的层序遍历就是奇数层从右到左,偶数层从左到右。其实也就是判断一下奇偶然后利用collections.reverse来反转一下
class solution{
public List<List<Integer>> zigzagLevelOrder(TreeNode root){
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean zig = false;
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
if(zig == true){
Collections.reverse(level);
}
res.add(level);
zig = !zig;
}
return res;
}
}
Binary Tree vertical level traversal
这一题就稍微有一点复杂了,需要我们从左到右的垂直顺序遍历二叉树,最左的节点为第一个,这一题我们可以用一个哈希表来存储列数和节点,如果根节点是0列,那么左子节点就是0-1,右子节点就是0+1的列数。
class Solution {
public List<List<Integer>> verticalOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(root==null)
return result;
// level and list
HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
LinkedList<Integer> level = new LinkedList<Integer>();
queue.offer(root);
level.offer(0);
int minLevel=0;
int maxLevel=0;
while(!queue.isEmpty()){
TreeNode p = queue.poll();
int l = level.poll();
//track min and max levels
minLevel=Math.min(minLevel, l);
maxLevel=Math.max(maxLevel, l);
if(map.containsKey(l)){
map.get(l).add(p.val);
}else{
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(p.val);
map.put(l, list);
}
if(p.left!=null){
queue.offer(p.left);
level.offer(l-1);
}
if(p.right!=null){
queue.offer(p.right);
level.offer(l+1);
}
}
for(int i=minLevel; i<=maxLevel; i++){
if(map.containsKey(i)){
result.add(map.get(i));
}
}
return result;
}
}
利用哈希表的映射,我们就可以储存垂直层级和节点之间的关系,利用BFS找到这个关系,再存储金哈希表里就可以完成这个问题了。