LeetCode 102 二叉树的层序遍历
二叉树层序遍历的模板,使用队列来完成。由于需要将每一层的节点放在一起,所以我们每次遍历新的一层的时候,记录下当前队列的大小,因为当前队列的大小就代表当前层的节点数!要用一个变量来记录当前队列大小,而不能直接使用deque.size(),因为deque.size()是变化的!随着你在遍历这一层并不断将它们的左右儿子推入队列中,deque.size()是一直在变大的,并不能代表当前正在遍历的层的节点个数!
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
List<List<Integer>> ans = new ArrayList<>();
if (root == null)
return ans;
while (!deque.isEmpty()) {
int size = deque.size();
List<Integer> tmpList = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
tmpList.add(node.val);
if (node.left != null)
deque.offer(node.left);
if (node.right != null)
deque.offer(node.right);
}
ans.add(tmpList);
}
return ans;
}
}
LeetCode 107 二叉树的层序遍历 II
跟上道题是差不多的,差别在于是自底向上的层序遍历,只要在最后用Collections.reverse() 方法将结果反转一下就行了
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
List<List<Integer>> ans = new ArrayList<>();
if (root == null)
return ans;
while (!deque.isEmpty()) {
int size = deque.size();
List<Integer> tmpList = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
tmpList.add(node.val);
if (node.left != null)
deque.offer(node.left);
if (node.right != null)
deque.offer(node.right);
}
ans.add(tmpList);
}
Collections.reverse(ans);//关键代码在这里!!!
return ans;
}
}
LeetCode 199 二叉树的右视图
这道题是要返回从右侧所能看到的节点值
做这道题的时候思路注意还是得往二叉树的层序遍历上靠,仍然是使用二叉树层序遍历模板!
那么如何判断一个节点是否是在当前层的最右边?如果它是在最右边,那么在遍历它上一层的时候,它会是最后一个被推入队列中的!
我们在代码中有使用一个size变量来记录一个层的节点数,并用一个for循环来遍历这一层。那么当在for循环遍历中发现当前节点是当前层最后一个节点时,将它记录下来就可以了!在代码中已注明!
class Solution {
public List<Integer> rightSideView(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
List<Integer> ans = new ArrayList<>();
if (root == null)
return ans;
while (!deque.isEmpty()) {
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
if(i == size - 1)ans.add(node.val);//关键代码在这里!!!
if (node.left != null)deque.offer(node.left);
if (node.right != null)deque.offer(node.right);
}
}
return ans;
}
}
LeetCode 637 二叉树的层平均值
仍然使用二叉树的层序遍历模板,遍历每一层的时候记录当前层的节点值的和,最后再将和除以当前层的节点个数都得到当前层的平均值了
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> ans = new ArrayList<>();
if (root == null)
return ans;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
double sum = 0;
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
if (node.left != null)
deque.offer(node.left);
if (node.right != null)
deque.offer(node.right);
sum += node.val;//关键代码在这里!!!
}
ans.add(sum / size);//关键代码在这里!!!
}
return ans;
}
}
LeetCode 429 N叉树的层序遍历
跟二叉树层序遍历其实大同小异,区别仅仅只是二叉树在对每一个节点进行处理时是将它的左右儿子推入队列,而N叉树就把节点的所有儿子都推入队列就行了
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> ans = new ArrayList<>();
if (root == null)
return ans;
Deque<Node> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
List<Integer> tmpList = new ArrayList<>();
for (int i = 0; i < size; i++) {
Node node = deque.poll();
tmpList.add(node.val);
if (node.children != null)//关键代码在这里!!!
for (Node tmp : node.children)
deque.offer(tmp);
}
ans.add(tmpList);
}
return ans;
}
}
LeetCode 515 在每个树行中找最大值
仍然是二叉树的层序遍历,遍历每一层的时候取当前层节点中的最大值即可
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if (root == null)
return ans;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
int rnBiggest = 0;
for (int i = 0; i < size; i++) {
TreeNode rnNode = deque.poll();
if (i == 0)
rnBiggest = rnNode.val;//关键代码在这里!!!
else
rnBiggest = rnBiggest >= rnNode.val ? rnBiggest : //关键代码在这里!!!rnNode.val;
if (rnNode.left != null)
deque.offer(rnNode.left);
if (rnNode.right != null)
deque.offer(rnNode.right);
}
ans.add(rnBiggest);
}
return ans;
}
}
LeetCode 116 填充每个节点的下一个右侧节点指针
依然是二叉树的层序遍历。在每一层的遍历时记录上一个节点,然后将当前节点赋给上一个节点的next指针。
class Solution {
public Node connect(Node root) {
if (root == null)
return root;
Deque<Node> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
Node rnParent = null;
for (int i = 0; i < size; i++) {
Node rnNode = deque.poll();
if (i != 0)
rnParent.next = rnNode;//关键代码在这里!!!
rnParent = rnNode;//关键代码在这里!!!
if (rnNode.left != null)
deque.offer(rnNode.left);
if (rnNode.right != null)
deque.offer(rnNode.right);
}
}
return root;
}
}
LeetCode 117 填充每个节点的下一个右侧节点指针 II
这题跟上一道题的区别就在于上一道题题目所给的树是满二叉树,这道题没有要求需要是满二叉树。但是上一道题的解决方法其实跟一棵树是不是满二叉树没有关系,所以直接用上一道题的代码也能过这道题
LeetCode 104 二叉树的最大深度
求二叉树的最大深度,每遍历到新的一层的时候深度+1即可。
class Solution {
public int maxDepth(TreeNode root) {
if (root == null)
return 0;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int depth = 0;
while (!deque.isEmpty()) {
depth++;//关键代码在这里!!!
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode rnNode = deque.poll();
if (rnNode.left != null)
deque.offer(rnNode.left);
if (rnNode.right != null)
deque.offer(rnNode.right);
}
}
return depth;
}
}
LeetCode 111 二叉树的最小深度
这道题跟上一道题是类似的,只不过它求的是最小深度。当我们在遍历过程中遇到第一个没有儿子的节点,那么这个节点所处的层次数就是这棵树的最小深度。
class Solution {
public int minDepth(TreeNode root) {
if (root == null)
return 0;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int depth = 0;
while (!deque.isEmpty()) {
depth++;
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode rnNode = deque.poll();
if(rnNode.left==null&&rnNode.right==null)//关键代码在这里!!!
return depth;
if (rnNode.left != null)
deque.offer(rnNode.left);
if (rnNode.right != null)
deque.offer(rnNode.right);
}
}
return depth;
}
}