层序遍历 leetcode链接
思考
使用LinkedList(双向链表)模拟队列,将二叉树的每一层数据暂存到队列中。开始时如果root节点不为空,就将root节点加入到队列中。进入第一个while循环循环的条件是!queue.isEmpty(),在循环中得到queue的size(),并将其记录下来记为size,即为queue中保存的上一层的节点的个数。再进入第二个while循环,循环的条件是size-- > 0,将queue中的每一个节点都poll出来,并分别判断其左右子节点是否为null,如果不为null就将其放入到queue中,直到size等于0,此时queue中保存的是下一层的节点,遍历完一层就将list放到result集合中再进行下一层的遍历,遍历完所有层,返回result集合。
代码展示
public class LevelOrder {
public List<List<Integer>> levelOrder(TreeNode root) {
ArrayList<List<Integer>> result = new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
if (root == null) {
return result;
}
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList<Integer> list = new ArrayList<>();
while (size-- > 0) {
TreeNode node = queue.poll();
list.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
result.add(list);
}
return result;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
总结
队列的特点是先进先出,符合层序遍历一层一层遍历的逻辑,适合广度优先遍历。而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
226.翻转二叉树 leetcode链接
思考
反转二叉树,即将二叉树的每个节点的左右子节点进行交换
代码展示
public TreeNode invertTree(TreeNode root) {
TreeNode cur = root;
TreeNode temp;
if (cur != null) {
temp = cur.left;
cur.left = cur.right;
cur.right = temp;
invertTree(cur.left);
invertTree(cur.right);
}
return root;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
总结
本题确实非常简单,但是容易被翻转二叉树“唬住”,需要明确的是翻转二叉树,就是将二叉树的每个节点的左右子节点进行翻转,这也是这段递归代码的单层逻辑
101.对称二叉树 2 leetcode链接
思考
判断是否为对称二叉树判断的不是判断左右节点是否相同,而是判断根节点的两个左右子树是否相同,这就说明了本题只能使用后序遍历的方式进行判断,同时分为外侧和内侧进行比较,即先判断外/内测的节点的叶子节点是否对称,再将结果返回给上一层节点进行判断,最终将整个子树的判断结果返回给根节点的左右子节点进行最后的比较。
代码展示
public class IsSymmetric {
public boolean isSymmetric(TreeNode root) {
return compare(root.left,root.right);
}
public boolean compare(TreeNode left,TreeNode right){
if (left == null && right != null) {
return false;
} else if (left != null && right == null) {
return false;
} else if (left == null && right == null) {
return true;
} else if (left.val != right.val) {
return false;
}else {
boolean outCompare = compare(left.left, right.right);
boolean inCompare = compare(left.right, right.left);
boolean compare = outCompare && inCompare;
return compare;
}
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
总结
只有判断了两个节点的子树是否对称才能返回判断这两个节点是否对称,这便决定了这道题只能使用后序遍历进行判断