力扣爆刷第141天之二叉树十连刷(层序遍历)
文章目录
- 力扣爆刷第141天之二叉树十连刷(层序遍历)
- 一、102. 二叉树的层序遍历
- 二、107. 二叉树的层序遍历 II
- 三、199. 二叉树的右视图
- 四、637. 二叉树的层平均值
- 五、429. N 叉树的层序遍历
- 六、515. 在每个树行中找最大值
- 七、116. 填充每个节点的下一个右侧节点指针
- 八、117. 填充每个节点的下一个右侧节点指针 II
- 九、104. 二叉树的最大深度
- 十、111. 二叉树的最小深度
一、102. 二叉树的层序遍历
题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
思路:层序遍历,使用队列完成,经典题目。通过队列size来控制层序遍历。
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/
思路:要求从叶子层到根节点层进行层序遍历,直接层序遍历,然后翻转数组。
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时记录数据。也可以直接前序遍历,只不过遍历的顺序是右中左,而且维护一个深度值,只有每次突破深度时才记录。
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算平均值。
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循环,把子节点全遍历出来。
/*
// 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/
思路:没啥东西,就是层序遍历,遍历每一层,然后比较获取最大值。
/*** 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/
思路:要求横向连接完美二叉树,本题可以层序遍历,遍历时先添加右子树再添加左子树。也可以使用递归,递归的话,每次递归传入左右两个节点,然后让左节点指向右节点。
/*
// 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/
思路:上一题是完全二叉树,可以使用递归来做,本题是普通二叉树,使用层序遍历会简单很多,具体解法和上一题一致。
/*
// 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/
思路:本题还是使用递归吧,后序遍历直接解决,使用层序遍历,只需要记录层的个数就可以大材小用了。
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/
思路:可以使用递归,用一个全局变量记录最小深度,然后在递归函数的参数中携带当前深度,直接遍历就行了,在叶子节点收集结果。
也可以层序遍历,只需要在每一层层序遍历时,记录叶子节点,只要发现叶子节点即可返回。
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);}
}