102. 二叉树的层序遍历
题目描述
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000
思路
DFS(深度优先搜索)和 BFS(广度优先搜索)
DFS:全称为 Depth-First Search(深度优先搜索),是一种用于遍历或搜索树或图的算法,其策略
是尽可能深地探索分支,直到无法继续为止,再回溯到上一个节点。
BFS:全称为 Breadth-First Search(广度优先搜索),同样用于树或图的遍历,其特点是按层级逐步扩展搜索范围,优先访问相邻的所有节点。
BFS
这里,我们可以分析处理,题目要求的层序遍历,其实就是BFS,代码如下
void bfs(TreeNode root) {Queue<TreeNode> queue = new ArrayDeque<>();queue.add(root);while (!queue.isEmpty()) {TreeNode node = queue.poll(); // Java 的 pop 写作 poll()if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}
}
但是BFS在遍历过程中,是没有保存这个节点所属的层级,因此,我们需要去设置一个变量,保存这个当前层级会有多少个元素,
通过观察这个遍历过程发现:当前这个层级结点个数 为 已出栈结点(上一层出栈的结点)的 左右子元素个数
上一层的所有结点,保存在了队列中
所以,通过上面的思路,便出现下面这个代码
上述题解:来源
DFS
其实DFS解决也比较简单,我们已知:DFS 遍历使用 递归,代码如下
void dfs(TreeNode root) {if (root == null) {return;}dfs(root.left);dfs(root.right);
}
因为需要记录每一层的元素,所以,我们需要定义一个变量deep,说明当前是在那一层
设所求为res,通过判断 res.size() < deep+1
,可知
- true:说明当前res少一层,所以需要 res.add(new ArrayList<>())
- false:说明当前正在遍历这一层
- 为什么要+1?小于说明现在是下一层了,res需要加1,和当前遍历保持在同层,如果大于则说明现在正好是当前层
通过对比,使用DFS后,复杂度比BFS低一点
代码
BFS
/*** 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 {public List<List<Integer>> levelOrder(TreeNode root) {if(root == null) {return new ArrayList<>();}Queue<TreeNode> queue = new ArrayDeque<>();queue.add(root);List<List<Integer>> res = new ArrayList<>();while(!queue.isEmpty()){int size = queue.size();List<Integer> list = new ArrayList<>();for(int i=0;i<size;++i){TreeNode node = queue.poll();if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}list.add(node.val);}res.add(list);}return res;}
}
DFS
/*** 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 {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();DFS(res, root, 0);return res;}public void DFS(List<List<Integer>> res, TreeNode node, int deep){if(node == null){return;}if(res.size() < deep + 1){res.add(new ArrayList<>());}res.get(deep).add(node.val);DFS(res, node.left, deep+1);DFS(res, node.right, deep+1);}
}