Day13|二叉树的层序遍历+翻转+对称

二叉树的层序遍历

这里主要看了借助队列的方式

        1.new一个新的队列

        2.如果根结点不为空的话,将结点添加进队列中

        3.当队列不为空时进入循环

        首先设置变量记录当前队列的size,此处记录了每层的元素个数,也决定了下一个循环循环几次,当size>0时记录将这一层的每个结点值添加进list中,将这一层节点的左右结点添加进队列。

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        List<List<Integer>> list = new ArrayList<>();
        if(root==null){return list;}
        while(!q.isEmpty()){
            int size = q.size();
            List<Integer> list1 = new ArrayList<>();
            while(size>0){
                TreeNode tn = q.poll(); 
                list1.add(tn.val);
                if(tn.left!=null){
                    q.offer(tn.left);
                }
                if(tn.right!=null){
                    q.offer(tn.right);
                }
                size--;

            }
            list.add(list1);

            

        }
    return list;
    }
}

102. 二叉树的层序遍历  在进入下一层循环之前,new一个list,最后将这个list添加进结果list中

107. 二叉树的层序遍历 II 相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。

199. 二叉树的右视图 遍历每一层,但是在list中只添加每一层的最后一个元素

637. 二叉树的层平均值 给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

515. 在每个树行中找最大值 层序遍历,取每一层的最大值

116.填充每个节点的下一个右侧节点指针 (小绕)

本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了,先poll()一个作为第一个结点,再进入for循环poll()出第二个结点,让第一个结点的next指向下一个结点。 

117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)同116仅在题目描述上有区别,答案相同

104. 二叉树的最大深度 定义一个depth变量,每次进入新的一层都++

111. 二叉树的最小深度定义一个depth变量,每次进入新的一层都++,但是上面一题是结束循环之后返回depth,此处是如果遇到一个节点的左子节点和右子节点都为空就返回,因为此时就是它的最小深度。


226.翻转二叉树

初始思路&&题解复盘:

利用递归来解决问题,输入当前节点,然后交换左右节点,此处利用递归,

交换左子节点的左右节点,交换右子节点的左右节点。

递归三部曲:

1.确定递归函数的参数和返回值

参数就是要传入节点的指针,返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*

2.确定终止条件

当前节点为空的时候,就返回

3.确定单层递归的逻辑

因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

迭代法大致思路,每次while循环中:交换根节点的左右节点然后push右节点入栈push左节点入栈

层序遍历:进入每层也是交换根节点左右节点然后将其左右子节点offer进入队列

注意迭代的中序:

因为先交换左节点的左右节点,在交

换根节点的左右节点,再交换右节点(此时交换的右节点就是原来的左子节点所以代码应该这么写

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        invertTree(root->left);         // 左
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
        return root;
    }
};

 


101. 对称二叉树

初始思路&&题解复盘:

        一定要使用后序遍历!!只有确定了其左子树和右子树对称,才能确定这个根节点和另一个根节点是对称的

递归三部曲

  1. 确定递归函数的参数和返回值

因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点

返回值自然是bool类型

        2.确定终止条件

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点

  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,返回true

此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

  • 左右都不为空,比较节点数值,不相同就return false

 3.确定单层递归的逻辑此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
  • 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
  • 如果左右都对称就返回true ,有一侧不对称就返回false 
        /**
         * 递归法
         */
        public boolean isSymmetric1(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;
        }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值