102. 二叉树的层序遍历|226. 翻转二叉树|101. 对称二叉树

题目

力扣

思路

所谓层序遍历,就是一层一层的遍历。

输出的结果是这样:二维数组,二维数组中的一维数组是这层节点的value。

借助了队列的结构。

每个节点弹出时,把自己的孩子节点加到队列里面。

如果只是单纯地把孩子加入,那么在队列中就会出现这个问题:队列中的节点,哪些是第n层的节点?哪些是第n-1层的节点?

所以在节点加入的时候,要用size进行记录,size是当前节点层的节点个数。

核心

  • 节点弹出,并记录节点
  • push节点的左右孩子
  • 两层while循环
    • 外层的while循环由queue内的节点数控制,无节点时停止
    • 内层的while循环由size控制,本层的节点遍历完停止
var levelOrder = function(root) {
    if(root == null) {
        return [];
    }
    let queue = [];
    let arr = [];
    let res = [];
    let size = 0;

    queue.push(root);
    
    while(queue.length != 0) {
        size = queue.length;
        while(size-- > 0) {
            let node = queue.shift();
            // 注意这里,push进去的应该是个值,而不是整个节点
            arr.push(node.val);

            if(node.left != null) {
                queue.push(node.left);
            }
            if(node.right != null) {
                queue.push(node.right);
            }
        }
        res.push(arr);
        arr = [];
    }

    return res;
};

力扣

思路

前序遍历,交换每个节点的左右孩子

var invertTree = function(root) {
    // []的这种情况怎么处理
    if (root == null) {
        return null;
    }

    let node = root.left;
    root.left = root.right;
    root.right = node;

    invertTree(root.left);
    invertTree(root.right);
    return root;
};

题目

力扣

解法一:

失败。

超出时间限制

var isSymmetric = function(root) {
    let queue = [];
    let size = 0;
    queue.push(root);

    while(queue.length != 0) {
        size = queue.length;
        while(size-- > 0) {
            let node = queue.shift();
                queue.push(node.left);
                queue.push(node.right);
        }
            let i = 0;
            let j = queue.length - 1;
            while(i < j) {
                // 1.两个都是null
                // 2.一个null,一个不是null
                // 3.两个都不是null
                if(queue[i] == null && queue[j] == null){
                    continue;
                }
                if(queue[i] == null || queue[j] == null){
                    return false;
                }
                if(queue[i].val != queue[j].val) {
                    return false;
                }
                i++;
                j--;
            }
    }

解法二:

迭代法

判断是否对称,其实是比较每一层的对应位置节点值是否相等。

因为这个操作是在“每一层”中进行的,所以很自然的想到在层序遍历的基础上做修改。

这里其实和层序遍历很相似,不同的地方是:

  • 层序遍历弹出一个节点,放入本节点的左右节点;而本题是弹出两个节点,放入两个节点的左右节点共四个节点
  • 层序遍历放入节点的顺序是从左到右依次放入;而本题是先放入外侧两个节点,再放入内侧的两个节点。
  • 本题需要比较弹出的两个节点。
var isSymmetric = function(root) {
    let queue = [];
    queue.push(root.left);
    queue.push(root.right);

    while(queue.length != 0) {
        let leftNode = queue.shift();
        let rightNode = queue.shift();

        // 两个节点都是空,只能说用continue,跳过当前这次的循环。
        // 那为什么下面就可以return false呢?
        // 因为一个反例就可以推倒所有
			
        if(leftNode == null && rightNode == null) {
            continue;
        }else if(leftNode != null && rightNode == null) {
            return false;
        }else if(leftNode == null && rightNode != null) {
            return false;
        }else if(leftNode.val != rightNode.val) {
            return false;
        }
        queue.push(leftNode.left);
        queue.push(rightNode.right);
        queue.push(leftNode.right);
        queue.push(rightNode.left);
    }

    return true;

};
递归法
  • 后序遍历,收集信息
  • 收集以下的信息:

  左子树、右子树-外侧是否相等

  左子树、右子树-内侧是否相等

  • 整合

 外侧、内侧都相等,对称。

var compare = function(leftNode, rightNode) {
    if(leftNode == null && rightNode == null) {
        return true;
    }else if(leftNode == null || rightNode == null) {
        return false;
    }else if(leftNode.val != rightNode.val) {
        return false;
    }

    let outside = compare(leftNode.left, rightNode.right);
    let inside = compare(leftNode.right, rightNode.left);
    return outside && inside;
}

难点:

  1. 这道题的参数应该是两个,这样才能比较
  2. 以往的终止条件是到叶子节点;本题终止条件是两个节点的比较
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值