给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
思路
主要思路就是先用BFS遍历得到一个层序遍历的结果集合,然后再对这个集合里的各个元素按层次分类,每个相同层次的元素是一个List
,最后再将这些相同层次的List
依次放在总的List
里。
主要问题:
题目定义的TreeNode
并没有写相关的层次信息,所以我们要自己重新写一个类,以此绑定相应结点和它所在的层次关系(我写的是Node
,主要包含树节点本身node
,和它所在的层次layer
)。
这里推荐再在自己定义的Node
类里面写一个构造函数,这样的话,当要入队树节点的孩子结点时,代码上不会显得特别复杂。例如想要入队左孩子时,只要直接new
一个lchild
,然后在构造函数里写相应信息就行了。
代码
public class Solution {
public static class TreeNode {//为了方便本地调试调用内部类,我写了静态的
//实际提交时可以不写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 Node{
TreeNode node;
int layer;
Node(TreeNode node, int layer){
this.node = node;
this.layer = layer;
}
}
Queue<Node> queue = new LinkedList<Node>();//可以用LinkedList当做队列来用(LinkedList实现了Queue接口)
ArrayList<Node> path = new ArrayList<Node>();
List<List<Integer>> finalPath = new ArrayList<List<Integer>>();
public void bfs(Node root) {
queue.offer(root);//将根结点入队
root.layer = 1;
while(queue.isEmpty()==false) {
Node topNode = queue.peek();//取出队首元素
queue.poll();//队首元素出队
path.add(topNode);
if(topNode.node.left!=null) {
Node lchild = new Node(topNode.node.left, topNode.layer+1);//先定好左右孩子的层号
queue.offer(lchild);//再入队
}
if(topNode.node.right!=null) {
Node rchild = new Node(topNode.node.right, topNode.layer+1);
queue.offer(rchild);
}
}
}
public List<List<Integer>> levelOrder(TreeNode root){
if(root!=null) {
Node r = new Node(root, 1);
bfs(r);
ArrayList<Integer> sameLayer = new ArrayList<Integer>();
int nowLayer = 1;
for(int i=0;i<path.size();i++) {
if(path.get(i).layer==nowLayer) {
sameLayer.add(path.get(i).node.val);
if(i==path.size()-1) {
ArrayList<Integer> finalTmp = new ArrayList<Integer>();
for(int j=0;j<sameLayer.size();j++) {
finalTmp.add(sameLayer.get(j));
}
finalPath.add(finalTmp);
sameLayer.removeAll(sameLayer);
}
}
else {
ArrayList<Integer> tmp = new ArrayList<Integer>();
for(int j=0;j<sameLayer.size();j++) {
tmp.add(sameLayer.get(j));
}
finalPath.add(tmp);
sameLayer.removeAll(sameLayer);
nowLayer++;
sameLayer.add(path.get(i).node.val);
if(i==path.size()-1) {
ArrayList<Integer> finalTmp = new ArrayList<Integer>();
for(int j=0;j<sameLayer.size();j++) {
finalTmp.add(sameLayer.get(j));
}
finalPath.add(finalTmp);
sameLayer.removeAll(sameLayer);
}
}
}
}
return finalPath;
}
}