二叉树的中序遍历

递归
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
inorder(root, ans);
return ans;
}
public void inorder(TreeNode root, List<Integer> ans) {
if (root == null) return;
inorder(root.left, ans);
ans.add(root.val);
inorder(root.right, ans);
}
}
二叉树的最大深度

递归计算
java
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
// 左右子树的最大深度 + 1
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
}
深度优先搜索、广度优先搜索都可以做
翻转二叉树

一看也是个递归问题,翻转二叉树就是翻转左右子树,然后依次递归翻转子树的左右子树。
- 这里本来想通过交换左右的值来实现,但是不可以,比如左子树不为空,右子树为空就没办法做了
java
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
对称二叉树


递归
java
class Solution {
public boolean isSymmetric(TreeNode root) {
return isSymmetric1(root.left, root.right);
}
private boolean isSymmetric1(TreeNode l, TreeNode r) {
// 如果都为空,那就是相等
if (l == null && r == null) return true;
// 如果一个为空一个不为空那就是不相等
if (l == null && r != null || l != null && r == null) return false;
boolean r1 = isSymmetric1(l.left, r.right);
boolean r2 = isSymmetric1(l.right, r.left);
return r1 && r2 && l.val == r.val;
}
}
这两个 if 判断可以简化为
java
class Solution {
public boolean isSymmetric(TreeNode root) {
return isSymmetric1(root.left, root.right);
}
private boolean isSymmetric1(TreeNode l, TreeNode r) {
// 简化
if (l == null || r == null) return l == r;
boolean r1 = isSymmetric1(l.left, r.right);
boolean r2 = isSymmetric1(l.right, r.left);
return r1 && r2 && l.val == r.val;
}
}
迭代
使用队列,左队列记录左边节点,右队列记录右边节点,队列元素不能为空,那我们在遍历的时候,出现两个队列元素不相等的时候就可以直接判断不对称。
java
class Solution {
public boolean isSymmetric(TreeNode root) {
// 放入左右节点
Deque<TreeNode> queueLeft = new LinkedList<>() {{ if (root.left != null) add(root.left); }};
Deque<TreeNode> queueRight = new LinkedList<>() {{ if (root.right != null) add(root.right); }};
while (queueLeft.size() == queueRight.size() && queueLeft.size() > 0) {
// 分别取一个元素
TreeNode l = queueLeft.removeFirst();
TreeNode r = queueRight.removeFirst();
// 如果值不等那就不对称了
if (l.val != r.val) return false;
// 对应节点不对称,返回 false
if (l.left != null && r.right == null || l.left == null && r.right != null)
return false;
// 不为空则加入,此时经过前面的判断,现在只有都为空或者都不为空的情况
if (l.left != null)
queueLeft.add(l.left);
if (r.right != null)
queueRight.add(r.right);
if (l.right != null && r.left == null || l.right == null && r.left != null)
return false;
if (l.right != null)
queueLeft.add(l.right);
if (r.left != null)
queueRight.add(r.left);
}
return queueLeft.size() == queueRight.size();
}
}
有没有更简化的写法呢?这好多 if 啊!有,我们可以让队列存 null 值,取出来的时候再判断,并且用一个队列就可以,只要我们保证联系取出来的两个元素是对应关系就行
java
class Solution {
public boolean isSymmetric(TreeNode root) {
Deque<TreeNode> q = new LinkedList<>();
q.add(root.left);
q.add(root.right);
while (!q.isEmpty()) {
TreeNode l = q.removeFirst();
TreeNode r = q.removeFirst();
// 下一轮循环
if (l == null && r == null) continue;
// 断定不对称
if (l == null || r == null || l.val != r.val)
return false;
// 存入两对判断
q.offer(l.left);
q.offer(r.right);
q.offer(l.right);
q.offer(r.left);
}
return true;
}
}