随想录训练营Day15 | 107.二叉树的层次遍历 II, 226.翻转二叉树, 101. 对称二叉树
标签: LeetCode闯关记
1. 107.二叉树的层次遍历 II
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
Deque<TreeNode> deque = new LinkedList<>();
if(root == null){//出现问题: 忘记判断root所以抛出异常:java.lang.NullPointerException: Cannot read field "val" because the return value of "java.util.Deque.pollFirst()" is null'
return list;
}
deque.addLast(root);
while (! deque.isEmpty()){
List<Integer> levelList = new ArrayList<>();//用一维数组来记录每一层的节点值
int levelSize = deque.size();//用levelSize来记录每一层的个数,这样就不会分不清该层和下一层的元素
while(levelSize > 0){
TreeNode node = deque.peekFirst();
levelList.add(deque.pop().val);
if(node.left != null){
deque.addLast(node.left);
}
if(node.right != null){
deque.addLast(node.right);
}
levelSize--;
}
//完成一层遍历之后,将一维数组添加入二维数组list中
list.add(levelList);
}
//反转list即可得到自底向上的层序遍历
List<List<Integer>> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0 ; i--) {
result.add(list.get(i));
}
return result;
}
}
2. 226.翻转二叉树
- DFS: 前序遍历-递归法
class Solution {
public TreeNode invertTree(TreeNode root) {
if( root == null){
return root;
}
//中
swapChildren(root);
//左
invertTree(root.left);
//右
invertTree(root.right);
return root;
}
private void swapChildren(TreeNode root){
TreeNode temp = root.right;
root.right = root.left;
root.left = temp;
}
}
- BFS:层序遍历-用队列实现
//BFS-层序遍历-用队列实现
class Solution {
public TreeNode invertTree(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
if( root == null){
return root;
}
deque.add(root);
while (! deque.isEmpty()){
int len = deque.size();
while (len-- > 0){
TreeNode node = deque.pop();
swapChildren(node);
if(node.left != null){
deque.addLast(node.left);
}
if(node.right != null){
deque.addLast(node.right);
}
}
}
return root;
}
private void swapChildren(TreeNode root){
TreeNode temp = root.right;
root.right = root.left;
root.left = temp;
}
}
3. 101. 对称二叉树
- 错解
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right){
//终止条件
if(left == null && right != null){
return false;
}
if (left != null && right == null){
return false;
}
if(left == null && right == null){
return true;
}
if(left.val != right.val){
return false;
}
//比较外侧
boolean compareOutside = compare(left.left, right.right);
System.out.println("外侧的左边" + left.left);
if(left.left != null){System.out.println("外侧的左边的节点值" + left.left.val);}
System.out.println("外侧的右边" + right.right);
if(right.right != null){System.out.println("外侧的右边的节点值" + right.right.val);}
System.out.println("------");
//比较内侧
boolean compareInside = compare(left.right, right.left);
System.out.println("内侧的左边" + left.right);
if(left.right != null){System.out.println("内侧的左边的节点值" + left.right.val);}
System.out.println("内侧的右边" + right.left);
if(right.left != null){System.out.println("内侧的右边的节点值" + right.left.val);}
System.out.println("------");
System.out.println("------");
return compareInside && compareInside;//发现错误:手误打了两个comapreInside (无语...)
}
}
- 正解
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right){
//终止条件
if(left == null && right != null){
return false;
}
if (left != null && right == null){
return false;
}
if(left == null && right == null){
return true;
}
if(left.val != right.val){
return false;
}
//比较外侧
boolean compareOutside = compare(left.left, right.right);
//比较内侧
boolean compareInside = compare(left.right, right.left);
return compareOutside && compareInside;
}
}
相关题目: 100.相同的数
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
return compare(p,q);
}
private boolean compare(TreeNode p, TreeNode q) {
if (p == null && q != null) {
return false;
}
if (p != null && q == null) {
return false;
}
if (p == null && q == null) {
return true;
}
if (p.val != q.val) {
return false;
}
// 比较两树的左子树
boolean compareLeft = compare(p.left, q.left);
// 比较两树的右子树
boolean compareRight = compare(p.right, q.right);
return compareLeft && compareRight;
}
}
相关题目:572. 另一棵树的子树
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
//第一个递归,先判断两树是否相同
if(isSameTree(root,subRoot)){
return true;
}
//运行到此处,说明subroot != null;
//现在利用第二个递归,来找root里面有没有subRoot
//第二个递归的终止条件,root == null
if(root == null){
return false;
}
//第二个递归的每层递归操作: 1.判断是不是相同的树; 2.不是的话,看root的左子树或者右子树是不是和subRoot是相同的
if(isSubtree(root.left,subRoot) || isSubtree(root.right, subRoot)){
return true;
}else{return false;}
}
//利用递归法判断是否为相同树
private boolean isSameTree(TreeNode p, TreeNode q){
//递归的终止条件
if(p == null && q != null){
return false;
}
if(p != null && q == null){
return false;
}
if(p == null && q == null){
return true;
}
if(p.val != q.val){
return false;
}
boolean isSameLeftTree = isSameTree(p.left, q.left);
boolean isSameRightTree = isSameTree(p.right, q.right);
return isSameLeftTree && isSameRightTree;
}
}
4. 总结
有点晕,待总结, 其实递归理解得还不到位,自己写肯定有问题,需要复习.