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

一、二叉树的层序遍历

  1. 102 二叉树的层序遍历

题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/

思路:借助一个队列,先入队根节点,然后每出队一个节点,就将它的的left和right分别入队。

代码:

var levelOrder = function(root) {
    if (!root) {
        return [];
    }
    var result = [];
    var queue = [];
    queue.push(root);
    while (queue.length !== 0) {
        // 需要记一下这个时候队列的长度,就是这一层应该有几个节点
        var size = queue.length;
        var level = [];
        for (let i=0; i<size; i++) {
            var cur = queue.shift();
            level.push(cur.val);
            if (cur.left) {
                queue.push(cur.left);
            }
            if (cur.right) {
                queue.push(cur.right);
            }
        }
        result.push(level);
    }
    return result;
};

  1. 107 二叉树的层序遍历II

题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/

思路:先层序遍历,然后反转就好了

代码:

var levelOrderBottom = function(root) {
    if (!root) {
        return [];
    }
    var result = [];
    var queue = [];
    queue.push(root);
    while (queue.length !== 0) {
        // 需要记一下这个时候队列的长度,就是这一层应该有几个节点
        var size = queue.length;
        var level = [];
        for (let i=0; i<size; i++) {
            var cur = queue.shift();
            level.push(cur.val);
            if (cur.left) {
                queue.push(cur.left);
            }
            if (cur.right) {
                queue.push(cur.right);
            }
        }
        result.push(level);
    }
    return result.reverse();
};

  1. 199 二叉树的右视图

题目链接:https://leetcode.cn/problems/binary-tree-right-side-view/

思路:层序遍历,但只有遍历到一层的最后一个时才加入result

代码:

var rightSideView = function(root) {
    if (!root) {
        return [];
    }
    var queue = [];
    queue.push(root);
    var result = [];
    while (queue.length !== 0) {
        var size = queue.length;
        for (let i=size; i>0; i--) {
            var cur = queue.shift();
            if (i == 1) {
                result.push(cur.val);
            }
            if (cur.left) {
                queue.push(cur.left);
            }
            if (cur.right) {
                queue.push(cur.right);
            }
        }
    }
    return result;
};

  1. 637 二叉树的层平均值

题目链接:https://leetcode.cn/problems/average-of-levels-in-binary-tree/

代码:

var averageOfLevels = function(root) {
    if (!root) {
        return [];
    }
    var result = [];
    var queue = [];
    queue.push(root);
    while (queue.length !== 0) {
        var size = queue.length;
        var sum = 0;
        for (let i=0; i<size; i++) {
            var cur = queue.shift();
            sum += cur.val;
            if (cur.left) {
                queue.push(cur.left);
            }
            if (cur.right) {
                queue.push(cur.right);
            }
        }
        result.push(sum/size);
    }
    return result;
};

  1. 429 N叉树的层序遍历

题目链接:https://leetcode.cn/problems/n-ary-tree-level-order-traversal/

代码:

var levelOrder = function(root) {
    if (!root) {
        return [];
    }
    var result = [];
    var queue = [];
    var size = 1;
    queue.push(root);
    while (queue.length) {
        var list = [];
        for (let i=size; i>0; i--) {
            var node = queue.shift();
            list.push(node.val);
            for (const child of node.children) {
                queue.push(child);
            }
        }
        size = queue.length;
        result.push(list);
    }
    return result;
};

  1. 515 在每个树行中找最大值

题目链接:https://leetcode.cn/problems/find-largest-value-in-each-tree-row/

代码:

var largestValues = function(root) {
    if (!root) {
        return [];
    }
    var result = [];
    var queue = [];
    queue.push(root);
    while (queue.length !== 0) {
        var size = queue.length;
        var max = Number.MIN_VALUE;
        for (let i=0; i<size; i++) {
            var cur = queue.shift();
            max = cur.val > max ? cur.val : max;
            if (cur.left) {
                queue.push(cur.left);
            }
            if (cur.right) {
                queue.push(cur.right);
            }
        }
        result.push(max);
    }
    return result;
};

  1. 116 填充每个节点的下一个右侧节点指针

题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/

代码:

var connect = function(root) {
    if (!root) {
        return root;
    }
    var size = 1;
    var queue = [];
    queue.push(root);
    while (queue.length) {
        for (var i=size; i>0; i--) {
            var node = queue.shift();
            // 如果是这层最后一个节点,则让其指向null
            if (i === 1) {
                node.next = null;
            }
            // 如果不是的话,让其指向下一个节点,即队列口的元素
            else {
                node.next = queue[0];
            }
            if (node.left) {
                queue.push(node.left);
            }
            if (node.right) {
                queue.push(node.right);
            }
        }
        size = queue.length;
    }
    return root;
};

  1. 117 填充每个节点的下一个右侧节点指针II

题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/

代码:和上一题完全一样,本质上是不是完美二叉树对求解没有影响。

  1. 104 二叉树的最大深度

题目链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/

代码:

var maxDepth = function(root) {
    if (!root) {
        return 0;
    }
    var depth = 0;
    var queue = [];
    var size = 1;
    queue.push(root);
    while (queue.length) {
        for (let i=size; i>0; i--) {
            var node = queue.shift();
            if (node.left) {
                queue.push(node.left);
            }
            if (node.right) {
                queue.push(node.right);
            }
        }
        depth += 1;
        size = queue.length;
    }
    return depth;
};

  1. 111 二叉树的最小深度

题目链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree/

代码:

var minDepth = function(root) {
    if (!root) {
        return 0;
    }
    var queue = []
    var size = 1;
    var depth = 1;
    queue.push(root);
    while (queue.length) {
        for (let i=size; i>0; i--) {
            var node = queue.shift();
            if (!node.left && !node.right) {
                return depth;
            }
            if (node.left) {
                queue.push(node.left);
            }
            if (node.right) {
                queue.push(node.right);
            }
        }
        size = queue.length;
        depth += 1;
    }
    return depth;
};

二、226 翻转二叉树

  1. 题目链接:https://leetcode.cn/problems/invert-binary-tree/

  1. 思路:前序遍历,递归版本。这道题用前序和后序都比较方便,不能用中序。

递归三部曲:首先确定递归函数的返回值和参数,这个返回值就是root,参数也是root;其次是终止条件,遇到空节点,就返回它本身,即null;最后看处理逻辑,是应该交换目前节点的左右子树,然后对它们再依次翻转。

  1. 代码:

var invertTree = function(root) {
    // 递归法,前序遍历
    if (!root) {
        return root;
    }
    // 中
    [root.left, root.right] = [root.right, root.left];
    // 左
    invertTree(root.left);
    // 右
    invertTree(root.right);
    return root;
};
  1. 中序遍历为什么不行:中序遍历是左中右,先将左子树翻转完了,然后交换左右子树,再处理右子树,相当于是一直在处理同一边的子树。

三、101 对称二叉树

  1. 题目链接:https://leetcode.cn/problems/symmetric-tree/

  1. 思路:只能使用后序遍历,左右中,因为我们要不断地收集左右孩子的信息返回给上一个节点,才能知道以左节点为根节点的树和以右节点为根节点的树是否是可以相互翻转的。

  1. 代码:

var isSymmetric = function(root) {
    // 判断左右子树是否可以互相翻转,这里传入的是根节点的左右子树的头结点
    var compare = function (left, right) {
        if (left && !right) {
            return false;
        }
        else if (!left && right) {
            return false;
        }
        else if (!left && !right) {
            return true;
        }
        else if (left.val != right.val) {
            return false;
        }
        // 外侧节点,左节点的左孩子和右节点的右孩子
        var outside = compare(left.left, right.right);
        // 内侧节点,左节点的右孩子和右节点的左孩子
        var inside = compare(left.right, right.left);
        // 这里可以看出,左子树的遍历顺序是左右中,而右子树是右左中
        return inside && outside;
    }
    return compare(root.left, root.right)
};

  1. 100 相同的树

题目链接:https://leetcode.cn/problems/same-tree/

思路:递归方法比较左子树和右子树是否相等,这次相当于是用了前序遍历

代码:

var isSameTree = function(p, q) {
    if (!p && !q) {
        return true;
    }
    else if (!p || !q) {
        return false;
    }
    else if (p.val !== q.val) {
        return false;
    }
    // 相当于中左右,先判断了p和q的值相等,然后分别判断左右子树
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};

  1. 572 另一个树的子树

题目链接:https://leetcode.cn/problems/subtree-of-another-tree/

代码:

var isSubtree = function(root, subRoot) {
    //此题也类似判断两个二叉树是否相等
    const compare = function(left,right){
        if(!left && !right){
            return true;
        }
        else if(left!==null&&right===null||left===null&&right!==null||left.val!==right.val){
            return false;
        }
        let leftSide = compare(left.left,right.left);
        let rightSide = compare(left.right,right.right);
        let isSame = leftSide&&rightSide;
        return isSame;
    }
   if(root===null){
       return false
   }
   if(compare(root,subRoot)){
       return true;
   }
   return isSubtree(root.left,subRoot)||isSubtree(root.right,subRoot);
};

今日学习时间:4h左右

总结:层序遍历比较简单,但是后面两道题还没有做透,对称二叉树明天补。

更新:翻转二叉树使用的是前序遍历或后序遍历,而对称二叉树使用的是中序遍历,严格来讲左子树是左右中,右子树是右左中。下次再刷的时候需要注意226、101和572。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值