力扣爆刷第141天之二叉树十连刷(层序遍历)
文章目录
-
-
- 力扣爆刷第141天之二叉树十连刷(层序遍历)
- [一、102. 二叉树的层序遍历](#一、102. 二叉树的层序遍历)
- [二、107. 二叉树的层序遍历 II](#二、107. 二叉树的层序遍历 II)
- [三、199. 二叉树的右视图](#三、199. 二叉树的右视图)
- [四、637. 二叉树的层平均值](#四、637. 二叉树的层平均值)
- [五、429. N 叉树的层序遍历](#五、429. N 叉树的层序遍历)
- [六、515. 在每个树行中找最大值](#六、515. 在每个树行中找最大值)
- [七、116. 填充每个节点的下一个右侧节点指针](#七、116. 填充每个节点的下一个右侧节点指针)
- [八、117. 填充每个节点的下一个右侧节点指针 II](#八、117. 填充每个节点的下一个右侧节点指针 II)
- [九、104. 二叉树的最大深度](#九、104. 二叉树的最大深度)
- [十、111. 二叉树的最小深度](#十、111. 二叉树的最小深度)
-
一、102. 二叉树的层序遍历
题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
思路:层序遍历,使用队列完成,经典题目。通过队列size来控制层序遍历。
java
class Solution {
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null) return result;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
result.add(list);
}
return result;
}
}
二、107. 二叉树的层序遍历 II
题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/
思路:要求从叶子层到根节点层进行层序遍历,直接层序遍历,然后翻转数组。
java
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
if(root == null) return result;
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
result.add(list);
}
int i = 0, j = result.size()-1;
while(i < j) {
List<Integer> t = result.get(i);
result.set(i, result.get(j));
result.set(j, t);
i++;
j--;
}
return result;
}
}
三、199. 二叉树的右视图
题目链接:https://leetcode.cn/problems/binary-tree-right-side-view/description/
思路:本题可以直接层序遍历,只需要在每一层遍历到size时记录数据。也可以直接前序遍历,只不过遍历的顺序是右中左,而且维护一个深度值,只有每次突破深度时才记录。
java
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
if(root == null) return list;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if(i == size-1) {
list.add(node.val);
}
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
}
return list;
}
}
四、637. 二叉树的层平均值
题目链接:https://leetcode.cn/problems/average-of-levels-in-binary-tree/description/
思路:直接层序遍历,然后收集每一层的总和,利用size算平均值。
java
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> list = new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
double avg = 0;
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
avg += node.val;
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
list.add(avg/size);
}
return list;
}
}
五、429. N 叉树的层序遍历
题目链接:https://leetcode.cn/problems/n-ary-tree-level-order-traversal/description/
思路:N叉树的层序遍历,比二叉树来说,只是多了几个叉,不需要在直接写左右子树了,直接一个for循环,把子节点全遍历出来。
java
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> result = new ArrayList<>();
if(root == null) return result;
LinkedList<Node> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
for(int i = 0; i < size; i++) {
Node node = queue.poll();
list.add(node.val);
for(Node temp : node.children) {
if(temp != null) {
queue.add(temp);
}
}
}
result.add(list);
}
return result;
}
}
六、515. 在每个树行中找最大值
题目链接:https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/
思路:没啥东西,就是层序遍历,遍历每一层,然后比较获取最大值。
java
/**
* 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<Integer> largestValues(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null) return list;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
int max = Integer.MIN_VALUE;
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
max = Math.max(max, node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
list.add(max);
}
return list;
}
}
七、116. 填充每个节点的下一个右侧节点指针
题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/description/
思路:要求横向连接完美二叉树,本题可以层序遍历,遍历时先添加右子树再添加左子树。也可以使用递归,递归的话,每次递归传入左右两个节点,然后让左节点指向右节点。
java
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
LinkedList<Node> queue = new LinkedList<>();
if(root == null) return root;
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
Node p = null;
for(int i = 0; i < size; i++) {
Node node = queue.poll();
node.next = p;
p = node;
if(node.right != null) queue.add(node.right);
if(node.left != null) queue.add(node.left);
}
}
return root;
}
}
八、117. 填充每个节点的下一个右侧节点指针 II
题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/description/
思路:上一题是完全二叉树,可以使用递归来做,本题是普通二叉树,使用层序遍历会简单很多,具体解法和上一题一致。
java
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if(root == null) return root;
LinkedList<Node> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
Node p = null;
for(int i = 0; i < size; i++) {
Node node = queue.poll();
node.next = p;
p = node;
if(node.right != null) queue.add(node.right);
if(node.left != null) queue.add(node.left);
}
}
return root;
}
}
九、104. 二叉树的最大深度
题目链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/
思路:本题还是使用递归吧,后序遍历直接解决,使用层序遍历,只需要记录层的个数就可以大材小用了。
java
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left, right) + 1;
}
}
十、111. 二叉树的最小深度
题目链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/
思路:可以使用递归,用一个全局变量记录最小深度,然后在递归函数的参数中携带当前深度,直接遍历就行了,在叶子节点收集结果。
也可以层序遍历,只需要在每一层层序遍历时,记录叶子节点,只要发现叶子节点即可返回。
java
class Solution {
int min = Integer.MAX_VALUE;
public int minDepth(TreeNode root) {
if(root == null) return 0;
fun(root, 1);
return min;
}
void fun(TreeNode root, int v) {
if(root == null) return ;
if(root.left == null && root.right == null) {
min = Math.min(min, v);
return ;
}
fun(root.left, v+1);
fun(root.right, v+1);
}
}