代码随想录算法训练营第十五天 | 层序遍历、226.翻转二叉树、101. 对称二叉树

day_15

题目连接

102 - 二叉树的层序遍历

两种方法:

  • 递归(深度遍历,取出值,给每一个节点赋上以一个深度标记)
    • 将同一深度的节点值存储在一起,就得到了目标的层的层序遍历结果
public class LevelOrderTraversalRecursion {

    //  存储层序节点的 list
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        levelOrderRecursion(root, 0);

        return res;
    }

    public void levelOrderRecursion(TreeNode node, int deep){
        if (node == null)   return;
        deep++;         //  给节点的深度赋值

        //  res.size < deep 说明当前的深度还没有遍历到,给res 里新增一个存储当前深度的 list
        //  递归是使用深度遍历来获取层序单层节点,选用前序遍历的方式,获取到跟节点后就添加到目标数组里
        if (res.size() < deep) {
            List<Integer> item = new ArrayList<Integer>();
            res.add(item);
        }
        res.get(deep - 1).add(node.val);                //  中
        levelOrderRecursion(node.left, deep);           //  左
        levelOrderRecursion(node.right, deep);          //  右
    }
}
  • 迭代
    • 直接使用队列维护一整层的节点,继进行处理即可
public class LevelOrderTraversalQueue {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();            //  中序遍历的结果列表
        Queue<TreeNode> queue = new LinkedList<>();              //  对接口的实现如何查看?

        if (root == null) return res;

        queue.add(root);

        while (!queue.isEmpty()){
            int size = queue.size();                         //  上一层有几个
            List<Integer> upLevel = new ArrayList<>();

            while (size > 0){
                TreeNode cur = queue.poll();
                upLevel.add(cur.val);
                if (cur.left != null) queue.add(cur.left);
                if (cur.right != null) queue.add(cur.right);
                size--;
            }

            res.add(upLevel);
        }

        return res;
    }
}

226 - 翻转二叉树

  想要翻转它,其实就把每一个节点的左右孩子交换一下就可以了
  问题是:前中后序应该选哪一种遍历顺序?
  使用前序遍历处理子树,这是因为,
  反转是先将左右子树进行反转操作,再将子树的左右反转
  这种先操作根节点,再操作左右节点的顺序,正是前序遍历过程
typedef struct TreeNode TreeNode;

//  对二叉树操作的时候,一定要选择好遍历的顺序
struct TreeNode* invertTree(struct TreeNode* root){
    if (root == NULL){
        return NULL;
    }
    
    //  使用前序遍历处理子树,这是因为,
    //  反转是先将左右子树进行反转操作,再将子树的左右反转
    //  这种先操作根节点,再操作左右节点的顺序,正是前序遍历过程
    invert(root);
    
    return root;
}

//  在这里进行递归处理
void invert(TreeNode* root) {
    if (root == NULL)   return;

    TreeNode* temp = root -> left;
    root -> left = root -> right;
    root -> right = temp;

    invert(root->left);
    invert(root->right);
}

101 - 对称二叉树

  • 思路
    • 从跟节点逐渐向下判断,每一级的节点是否相同
    • 里面的情况中,不写 eles 是因为不为空且相同的时候,会自动走到这里
    • 如果一开始遇到 false 的情况,直接 return,不用向下继续遍历
    • 假设 outside 中间有跟节点不同,遍历到该节点的时候,就会直接 return false,不会继续向下了,会将该节点的判断结果一路返回
    • 再得出 inside 的匹配结果
    • 如果左右都对称就返回true ,有一侧不对称就返回false
typedef struct TreeNode TreeNode;

bool isSymmetric(struct TreeNode* root){
    if (root == NULL) return true;
    return judgeNodeSame(root->left, root->right);
}

//  后续遍历,需要先一路递归到叶子节点才行
bool judgeNodeSame(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;       //  左右不为空,且不相等,只剩左右相等的情况了

    //  左右相等,向下遍历
    bool outside = judgeNodeSame(left -> left, right -> right);                //  左
    bool inside = judgeNodeSame(left -> right, right -> left);                //  右

    bool isSame = outside && inside;                    // 左子树:中、 右子树:中 (逻辑处理)
    return isSame;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值