二叉树的序列化

二叉树的序列化

思路

  • 序列化:前序遍历("root.val" + "," + "root.left" + "," + "root.right")
  • *序列化的时候一定要带逗号,因为有可能数值为复数。
    在这里插入图片描述
  • 反序列化稍微复杂一点
    • 若弹出的是数字,则新建root节点,先反序列化根节点的左子树,再反序列化根结点的右子树。
    • 若弹出的是#,则返回null空指针
    • 坑1:反序列化时用.split(",")函数将字符串转为数组。
    • 坑2:即使遇到#,数组也要弹出该元素。

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
//  序列化以root为根的树
var serialize = function(root) {
    if(root==null){
        return "#";
    }else{
        return "" + root.val + "," + serialize(root.left) + "," + serialize(root.right);
    }
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
// 反序列化"2,1,#,6,#,#,3,#,#"
var deserialize = function(data) {

    // 全局数组,记录递归序列。
    let arrs = data.split(",");

    var deser = function(arrs){
        let val = arrs.shift();
        if(val=="#"){
            // 弹出的是#,则返回null空指针
            return null;
        }else{
            // 弹出的是数字,则新建root节点,先反序列化根节点的左子树,再反序列化根结点的右子树
            let root = new TreeNode(val);
            root.left = deser(arrs);
            root.right = deser(arrs);
            return root;
        }
    }

    return deser(arrs);
};

/**
 * Your functions will be called as such:
 * deserialize(serialize(root));
 */

寻找重复的子树

思路

  • 序列化每颗子树,并在序列化的同时,保存序列化结果。
  • 数据结构
    • 字典dic:{序列化字符串: 子树的根}
    • 字符串数组arr:保存重复出现的序列化字符串。
    • 通过遍历字符串数组,找到其对应的子树的根,即为重复出现的子树。

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode[]}
 */
var findDuplicateSubtrees = function(root) {

    // 全局变量dic(序列与root的一一对应关系)和arr(有重复的key)
    let dic = {};
    let arr = [];
    // 对root为根的节点序列化
    var series = function(root){
        if(root==null){
            return "#";
        }else{
            let key = root.val + "," + series(root.left) + "," + series(root.right);
            // key不存在,需要添加该root到字典中
            if(!dic[key]){
                dic[key] = root;
            }else{
                // key已经存在,且key没有被添加到ans中过。
                if(arr.indexOf(key)==-1){
                    arr.push(key);
                }
            }
            return key;
        }
    }
    series(root);
    // 遍历arr,找出ans中key对应的节点。
    let ans = []
    for(let i=0; i<arr.length; i++){
        ans.push(dic[arr[i]]);
    }
    return ans;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值