用javascript分类刷leetcode21.树(图文视频讲解)

树这种数据结构包括根节点root,左右节点,子树中又有父节点,子节点,兄弟节点,没有子节点的成为叶子节点,树分为二叉树和多叉树

ds_36

ds_37

List 就是特殊化的tree,Tree就是特殊化的Graph

二分搜索树

二分搜索树(英语:Binary Search Tree),也称为 有序二叉树或排序二叉树。满足以下几个条件:

  • 若它的左子树不为空,左子树上所有节点的值都小于它的根节点。
  • 若它的右子树不为空,右子树上所有的节点的值都大于它的根节点。
  • 它的左、右子树也都是二分搜索树。

二分搜索树的优势:不仅可以查找数据,还可以高效的插入、删除数据

ds_116

注意二分搜索树不一定是完全二叉树

ds_117

树的遍历
  • 深度优先
  • 广度优先

  1. 前序:根-左-右
  2. 中序:左-根-右
  3. 后序:左-右-根

ds_38

101. 对称二叉树 (easy)

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100

进阶:你可以运用递归和迭代两种方法解决这个问题吗?

方法1.dfs递归
  • 复杂度:时间复杂度O(n),每个节点遍历一次,空间复杂度O(n),递归栈深度,最深不超过n

js:

var isSymmetric = function(root) {
   
    if(!root) return true
    const isMirror = (l, r) => {
   
        if(!l && !r) return true; //两个空节点也为镜像
        if(
            l && r && l.val === r.val &&  //左节点和右节点相同,左子树和右子树也对称则返回true
            isMirror(l.left, r.right) && 
            isMirror(l.right, r.left)
        ) {
   
            return true;
        }
        return false;
    }
    return isMirror(root.left, root.right)
};
方法2.bfs
  • 复杂度:时间复杂度O(n),每个节点遍历一次,空间复杂度O(n),队列的空间

js:

function isSymmetric(root) {
   
    const isMirror = (l, r) => {
   
        const queue = [l, r];
        while (queue.length) {
   
            const u = queue.shift();
            const v = queue.shift();
            if (!u && !v) continue; //两个空节点也为镜像
            //左右节点只有一个节点为空,或者值不相同返回false
            if (!u || !v || u.val !== v.val) return false;
            queue.push(u.left, v.right); //加入左节点的左子树,右节点的右子树
            queue.push(v.left, u.right); //加入右节点的左子树,左节点的右子树
        }
        return true;
    };
    return isMirror(root.left, root.right);
}
100. 相同的树(easy)

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:

输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:

输入:p = [1,2,1], q = [1,1,2]
输出:false

提示:

两棵树上的节点数目都在范围 [0, 100] 内
-104 <= Node.val <= 104

方法1.dfs递归
  • 思路:递归比较左右子树
  • 复杂度:时间复杂度O(n),n是节点较少的树中的节点个数,递归有一个节点为null,另一个不为null就停止递归,空间复杂度O(n),递归深度不会超过节点个数

js:

var isSameTree = function(p, q) {
   
    if(p == null && q == null) //都是null表示相同
        return true;
    if(p == null || q == null) //只有一个是null表示不同
        return false;
    if(p.val != q.val) //节点的值不同
        return false;
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);//递归左右子树
};
方法2bfs:
  • 复杂度:时间复杂度O(n),n是节点较少的树中的节点个数,空间复杂度O(n),队列的空间不会超过节点较少的树中的节点个数

js:

var isSameTree = function(p, q) {
   
    let pQ = [p], qQ = [q], res = true

    while (pQ.length) {
   
        pNode = pQ.shift()
        qNode = qQ.shift()

        if (pNode === null && qNode === null) {
   
            res = true
        } else if (pNode === null || qNode === null) {
   
            res = false
            break 
        } else {
   
            if (pNode.val !== qNode.val) {
   
                res = false
                break 
            } else {
   
                pQ.push(pNode.left)
                pQ.push(pNode.right)

                qQ.push(qNode.left)
                qQ.push(qNode.right)
            }
        }
    }

    return res
};
297. 二叉树的序列化与反序列化 (hard)

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例 1:

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
示例 4:

输入:root = [1,2]
输出:[1,2]

提示:

树中结点数在范围 [0, 104] 内
-1000 <= Node.val <= 1000

方法1.递归dfs
ds_110
  • 思路:深度优先遍历,按根,左,右 返回字符串,方便反序列化的时候从根节点开始构建,递归左右子树,直到遇见了null节点。
  • 复杂度:时间复杂度O(n),每个节点访问一次,n是树的节点个数。空间复杂度O(n),最坏情况下递归深度是n

js:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值