【算法之LeetCode系列(5)】—— 二叉树系列(easy类)

LeetCode之二叉树系列

最近开始认真准备算法了,于是打开了大家都熟悉的算法小抄,摸索着里面高深的刷题方法,最后总结一下作者的意思就是心中想着那几个模板,然后往题目中套着做,而且推荐新手最先刷二叉树系列的题目,我觉得值得一试,于是这两天做了几个二叉树的题目,并且研究了一下,得出下面的二叉树刷题心得,如有错误之处,可以指出哈

我刷了这几个二叉树的题,基本都是可以用递归做出来的,所以对于递归我又有了新的认识,我觉得la哥还是挺有意思的(当然里面还有BFS,DFS)

五道题:

1. 相同的树
2. 对称二叉树
3. 二叉树的最大深度
4. 平衡二叉树
5. 二叉树的层序遍历(Medium)

题目描述我就不贴了,大家去官网上搜就OK了

1. 相同的树

var isSameTree = function(p, q) {
     
    if(q === null && p === null){
     //如果两棵“子”树都是空树,一定相同啊
        return true
    }
    //前面那个条件不满足,说明不是同时都是空树,所以只要其中有一个是空树,两棵树肯定不一样
    if(q === null || p === null){
     
        return false
    }
    //前面两个条件都不满足,说明都不是空树(比较结构),结构相同,接下来比较节点值,值不同,树不同
    if(q.val !== p.val){
     
        return false
    }
    //最后这里&&是一个短路效应,左子树或者右子树其中只要有一个不满足相同条件就是不同
    //同样如果左右子树都是相同的,那肯定是一样的
    //这里有递归,你不要去想具体的过程
    //你只需要知道,这里使用递归是检测每一个节点的左右子树是否相同就行
    return isSameTree(q.left,p.left) && isSameTree(q.right,p.right);
 };

1. 对称二叉树

因为做这个题之前做了相同的树,所以想了一会儿就有思路了,其实这和相同的树没什么区别,只不过相同的树比较的是两棵树的左子树是不是一样,右子树是不是一样,而这个对称其实就是比较树1的左子树和树2的右子树是不是一样,树1的右子树和树2的左子树是不是一样,所以,你是不是也有思路了……

var isSymmetric = function(root) {
     
	//先将这棵树拆分成两棵树root1和root2
    let root1 = root.left;
    let root2 = root.right;
    //接下来套路就和相同树一样了,只不过递归传递的值要变一下
    if(root1 === null && root2 === null)
        return true;
    if(root1 === null || root2 === null)
        return false;
    if(root1.val !== root2.val)
        return false;
    function isSame(left,right){
     
        if(left === null && right === null)
            return true
        if(left === null || right === null)
            return false
        if(left.val !== right.val)
            return false
        // 这里是比较树1的左子树和树2的右子树是不是一样,树1的右子树和树2的左子树是不是一样
        return isSame(left.left,right.right) && isSame(left.right,right.left)
    }
    return isSame(root1,root2)
};

3. 二叉树的最大深度

这个就比较简单的了。只需要递归计算左右子树的最大的深度,去最大的就行

var maxDepth = function(root) {
     
    if(!root){
     //如果是空树,或者是叶子节点,就返回0
        return 0;
    }else{
     
        const left = maxDepth(root.left);//找到左子树的最大深度
        const right = maxDepth(root.right);//找到右子树的最大深度
        return Math.max(left,right) + 1;//比较,取较大者
    }
};

4. 平衡二叉树

这里涉及什么是平衡二叉树,简单理解就是任意一个节点的左右子树的高度差小于等于1,而好巧不巧,二叉树的高度和深度是一样的,所以前一题的最大深度又可以复用啦……我怀疑我真的是故意找的(不是)

var isBalanced = function(root) {
     
    const maxDepth = function(root) {
     //求二叉树的最大深度
        if(!root){
     
            return 0;
        }else{
     
            const left = maxDepth(root.left);
            const right = maxDepth(root.right);
            return Math.max(left,right) + 1;
        }
    };
    if(!root)//如果是空树或者是当前是叶子结点
        return true;
    //下面这个return 语句按照&&划分。如果&&左右有一个条件不满足,就不是平衡二叉树
    //最后的return语句总结:当前节点的左右子树的高度差小于1,且左右子树的根节点也要满足这个条件
    //第一部分:是计算     当前节点      的左右子树的高度差是不是小于1(就是递归传入的节点还有最开始的根节点)
    //第二部分,计算当前节点的左子树是不是平衡二叉树
    //第三部分,计算当前节点的右子树是不是平衡二叉树
    //三部分的条件,如果有一个假了,绝不是平衡二叉树(傲娇)
    return Math.abs(maxDepth(root.left) - maxDepth(root.right)) <= 1 
    && isBalanced(root.left) && isBalanced(root.right)
};

4. 二叉树的层序遍历

层序遍历使用递归我是做不出来(递归受挫,刚培养起来的自信瞬间无了),需要使用广度优先遍历(BFS),而之前的最大深度其实也可以算是深度优先遍历(DFS),但是只是使用BFS是解决不了这个问题的,看注释!!!

var levelOrder = function(root) {
     
    let res = [];//存放最终结果
    let queue = [];//节点队列(队列是先进先出,js使用数组的shift和push可以模仿)
    if(root !== null){
     //当前节点不是空节点
        queue.push(root);//当前节点入队
    }
    
    while(queue.length > 0){
      //只要队列中还有节点
        let n = queue.length;//保存队列中节点个数
        let level = [];//   当前层  的节点
        for(let i = 0;i < n;i ++){
     //只要当前层还有节点,还是得接着遍历,可不能学BFS偷懒跑了
            let node = queue.shift();//头结点出队
            level.push(node.val);//当前层的节点依次   进入当前层
            if(node.left){
     //当前节点的左子节点,有则进入队列(注意,这里进入,但是n值不会变)
                queue.push(node.left);
            }
            //先左后右,同层由左向右进入队列
            if(node.right){
     //当前节点的右子节点,有则进入队列(注意,这里进入,但是n值不会变)
                queue.push(node.right);
            }
        }
        res.push(level);//当前层遍历完成,放入结果中
    }
    return res;
};

做了之后发现真的很“巧”,感觉做的题都是逐层递进的,通过这几个题,加深了我对递归,DFS,BFS这几个方法的理解,但是不够,还得继续!冲冲冲!

你可能感兴趣的:(算法之力扣系列,算法,leetcode,javascript,二叉树,递归算法)