难度: Medium
题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
二叉树的层序遍历
关于二叉树详细参考文章 数据结构与算法–Python–树
class Solution:
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
def dfs(node, level, res):
if not node:
return
if len(res) < level: # 如果该层还未初始化
res.append([])
res[level-1].append(node.val) # 当前node属于第level层
dfs(node.left, level+1, res) # node.left属于第level+1层
dfs(node.right, level+1, res) # node.right属于第level+1层
res = []
dfs(root, 1, res)
return res
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
dfs(res, root, 0);
return res;
}
private void dfs(List<List<Integer>> res, TreeNode root, int level) {
// 递归终止条件,root 为 null 则遍历结束
if (root == null) {
return;
}
// 根据 level 以及集合的大小判断是否需要加入新的层级,也就是新的的 List
if (level >= res.size()) {
res.add(new ArrayList<>());
}
res.get(level).add(root.val);
// 向下一个 level 中的左树进行遍历
dfs(res,root.left,level+1);
// 向下一个 level 中的左树进行遍历
dfs(res,root.right,level+1);
}
}
使用自己实现 LoopQueue 进行提交
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private interface Queue<E> {
int getSize();
boolean isEmpty();
void enqueue(E e);
E dequeue();
E getFront();
}
private class LoopQueue<E> implements Queue<E> {
private E[] data;
private int front, tail;
private int size; // 有兴趣的同学,在完成这一章后,可以思考一下:
// LoopQueue中不声明size,如何完成所有的逻辑?
// 这个问题可能会比大家想象的要难一点点:)
public LoopQueue(int capacity){
data = (E[])new Object[capacity + 1];
front = 0;
tail = 0;
size = 0;
}
public LoopQueue(){
this(10);
}
public int getCapacity(){
return data.length - 1;
}
@Override
public boolean isEmpty(){
return front == tail;
}
@Override
public int getSize(){
return size;
}
@Override
public void enqueue(E e){
if((tail + 1) % data.length == front)
resize(getCapacity() * 2);
data[tail] = e;
tail = (tail + 1) % data.length;
size ++;
}
@Override
public E dequeue(){
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
E ret = data[front];
data[front] = null;
front = (front + 1) % data.length;
size --;
if(size == getCapacity() / 4 && getCapacity() / 2 != 0)
resize(getCapacity() / 2);
return ret;
}
@Override
public E getFront(){
if(isEmpty())
throw new IllegalArgumentException("Queue is empty.");
return data[front];
}
private void resize(int newCapacity){
E[] newData = (E[])new Object[newCapacity + 1];
for(int i = 0 ; i < size ; i ++)
newData[i] = data[(i + front) % data.length];
data = newData;
front = 0;
tail = size;
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append(String.format("Queue: size = %d , capacity = %d\n", size, getCapacity()));
res.append("front [");
for(int i = front ; i != tail ; i = (i + 1) % data.length){
res.append(data[i]);
if((i + 1) % data.length != tail)
res.append(", ");
}
res.append("] tail");
return res.toString();
}
}
public List<List<Integer>> levelOrder(TreeNode root) {
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
if(root == null)
return res;
// 我们使用LinkedList来做为我们的先入先出的队列
LoopQueue<Pair<TreeNode, Integer>> queue = new LoopQueue<Pair<TreeNode, Integer>>();
queue.enqueue(new Pair<TreeNode, Integer>(root, 0));
while(!queue.isEmpty()){
Pair<TreeNode, Integer> front = queue.dequeue();
TreeNode node = front.getKey();
int level = front.getValue();
if(level == res.size())
res.add(new ArrayList<Integer>());
assert level < res.size();
res.get(level).add(node.val);
if(node.left != null)
queue.enqueue(new Pair<TreeNode, Integer>(node.left, level + 1));
if(node.right != null)
queue.enqueue(new Pair<TreeNode, Integer>(node.right, level + 1));
}
return res;
}
}