二叉树层序遍历
思路:利用队列来存储遍历的节点,同时要定义size来保存当前层的节点个数。
时间复杂度O(n)
直接上代码,所有层序遍历的题目都这样搞。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root == null) return ans;
Queue<TreeNode> que = new LinkedList<>();
que.add(root);
int size = 0;
while (!que.isEmpty()) {
size = que.size(); // 存储当前层的节点个数
List<Integer> temp = new ArrayList<>();
while (size-- > 0) {
TreeNode node = que.poll();
temp.add(node.val);
if (node.left != null) {
que.add(node.left);
}
if (node.right != null) {
que.add(node.right);
}
}
ans.add(temp);
}
return ans;
}
}
226.反转二叉树
思路:我是用层序遍历实现的,前序和后序的递归遍历也可以实现,中序的递归遍历实现逻辑较为复杂(不推荐)。迭代遍历也可以实现。(注意:是交换节点的左右子树(改变指针指向),而不是交换左右孩子的值。)
层序遍历实现
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Queue<TreeNode> que = new LinkedList<>();
que.add(root);
while (!que.isEmpty()) {
TreeNode node = que.poll();
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
if (node.left != null) {
que.add(node.left);
}
if (node.right != null) {
que.add(node.right);
}
}
return root;
}
}
前序递归遍历实现。
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;
}
}
后序递归遍历实现。
class Solution {
public TreeNode invertTree(TreeNode root) { // 递归后序实现
if (root == null) return null;
invertTree(root.left);
invertTree(root.right);
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
return root;
}
}
101.对称二叉树
思路:改题目其实是判断两棵树是否相同,只能采用后序遍历。根节点的左子树的遍历顺序为 左 右 中,根节点的右子树的遍历顺序为 右 左 中,都可以理解为后序遍历。
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right) {
if (left == null || right == null) {
if (left == null && right == null) {
return true;
} else {
return false;
}
}
if (left.val != right.val) return false;
boolean outside = compare(left.left, right.right);
boolean inside = compare(left.right, right.left);
return outside && inside;
}
}
补充:递归三部曲:1、确定递归函数的参数和返回值。2、确定终止条件。3、确定单层递归的逻辑。