层序遍历
102.二叉树的层序遍历
题目链接:二叉树的层序遍历
迭代法:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
int deep = 0;
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> list = new ArrayList<>();
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
list.add(temp.val);
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
result.add(list);
}
return result;
}
递归法:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
checkFun(root, 0, result);
return result;
}
void checkFun(TreeNode cur, int deep, List<List<Integer>> result) {
if (cur == null) return;
deep++;
if (result.size() < deep) {
List<Integer> list = new ArrayList<>();
result.add(list);
}
result.get(deep - 1).add(cur.val);
checkFun(cur.left, deep, result);
checkFun(cur.right, deep, result);
}
107.二叉树的层次遍历 II
最简单的思路就是直接把 102 的结果给反转一下,不过也可通过修改一部分代码,把每层列表添加在开头来解决。
迭代法
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> list = new ArrayList<>();
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
list.add(temp.val);
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
// 每层加在开头
result.add(0, list);
}
return result;
}
递归法
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
checkFun(root, 0, result);
return result;
}
void checkFun(TreeNode cur, int deep, List<List<Integer>> result) {
if (cur == null) {
return;
}
deep++;
if (result.size() < deep) {
// 反序,所以每次插入新数组在开头位置
result.add(0, new ArrayList<>());
}
// 添加值时也要计算一下索引
result.get(result.size() - deep).add(cur.val);
checkFun(cur.left, deep, result);
checkFun(cur.right, deep, result);
}
199.二叉树的右视图
迭代法,添加结果的时候判断是否到每层的最后一个。
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
if (i == len - 1) {
result.add(temp.val);
}
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
}
return result;
}
637.二叉树的层平均值
太简单啦。
public List<Double> averageOfLevels(TreeNode root) {
List<Double> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
double sum = 0;
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
sum += temp.val;
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
result.add(sum / len);
}
return result;
}
429.N 叉树的层序遍历
乱杀
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> list = new ArrayList<>();
int len = queue.size();
for (int i = 0; i < len; i++) {
Node temp = queue.poll();
if (temp == null) continue;
list.add(temp.val);
queue.addAll(temp.children);
}
result.add(list);
}
return result;
}
515.在每个树行中找最大值
就这
public List<Integer> largestValues(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Integer maxVal = Integer.MIN_VALUE;
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
maxVal = Math.max(temp.val, maxVal);
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
result.add(maxVal);
}
return result;
}
116.填充每个节点的下一个右侧节点指针
层序遍历,每层定义一个 Node next 变量,默认为空。重在在于入队列顺序改为从右开始,然后循环当前层节点的 next 进行赋值,同时吧 next 指向当前节点。
public Node connect(Node root) {
if (root == null) {
return root;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
Node next = null;
for (int i = 0; i < len; i++) {
Node temp = queue.poll();
if (temp.right != null) queue.offer(temp.right);
if (temp.left != null) queue.offer(temp.left);
temp.next = next;
next = temp;
}
}
return root;
}
117.填充每个节点的下一个右侧节点指针 II
额,同 116.填充每个节点的下一个右侧节点指针
104.二叉树的最大深度
public int maxDepth(TreeNode root) {
int depth = 0;
if (root == null)
return depth;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
depth++;
}
return depth;
}
111.二叉树的最小深度
子节点两边为空就结束。
public int minDepth(TreeNode root) {
int depth = 0;
if (root == null) return depth;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
depth++;
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
if (temp.left == null && temp.right == null) {
return depth;
}
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
}
return depth;
}
226.翻转二叉树
题目链接:力扣
这道题用前序遍历和后续遍历很好解,要注意中序遍历,容易让部分节点旋转两次,不推荐使用。
递归法:
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return root;
}
swapChild(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
void swapChild(TreeNode node) {
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
迭代法:
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return root;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode temp = queue.poll();
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
swapChild(temp);
}
}
return root;
}
void swapChild(TreeNode node) {
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
101.对称二叉树
题目链接:力扣
这道题重点要知道哪些节点进行比较,我们可以区分为两类,一个是外侧节点,一个是内测节点。
递归解法:
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right) {
if (left == null && right == null) {
return true;
}
if (left == null || right == null || left.val != right.val) {
return false;
}
boolean compareOutside = compare(left.left, right.right);
boolean compareInside = compare(left.right, right.left);
return compareOutside && compareInside;
}
递归法:
使用队列,一次性保存两对节点,然后每次比较也取出两对节点,如图所示:
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode left = queue.poll();
TreeNode right = queue.poll();
if (left == null && right == null) {
continue;
}
if (left == null || right == null || left.val != right.val) {
return false;
}
// 保存外侧
queue.offer(left.left);
queue.offer(right.right);
// 保存内测
queue.offer(left.right);
queue.offer(right.left);
}
return true;
}
总结
唯一的想法就是多复习。。