力扣链接:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/
题目描述
请实现两个函数,分别用来序列化和反序列化二叉树。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
序列化的形式不定,最终需要达到的效果是deserialize(serialize(root));可以还原原来的树。
思路
序列化的顺序显然为层序遍历,因此只需要在层序遍历过程中不断生成序列化字符串即可:
特殊情况:二叉树为空,返回“[]”
- 初始化结果字符串res=""
- 层序遍历,同时节点为空则 res+= "#," , 否则res+=`{node.val},`
- 用substring方法去掉最后一个“,”
- 返回 `[${res}]`
反序列化也类似层序遍历,用同样的逻辑实现一层一层从左至右地建树:
特殊情况,输入字符串为 "[]", 二叉树为空。
- 将字符串按“,”分割成数组nodes(字符串数组)
- 取出数组第一个元素,新建为root节点
- 新建队列数组queue,并将root入队
- 当queue非空:
- 取出queue队首,为当前需要处理的节点cur
- 取出nodes首元素,为cur的左儿子的值。若不是“#”,新建左儿子节点加入树,并入队列queue。
- 取出nodes首元素,为cur的右儿子的值。若不是“#”,新建右儿子节点加入树,并入队列queue。
- 返回root
(已经加入树中但儿子节点还没处理完的放在queue里,还没有被处理的放在nodes中,已经建好的节点出队)
代码:
/** * 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} */ var serialize = function(root) { if(!root) return "[]"; let res = ""; const queue = [root]; while(queue.length){ const head = queue.shift(); if(head){ res += `${head.val},`; queue.push(head.left); queue.push(head.right); }else{ res += "#,"; } } //删去最后一个, res = res.substring(0, res.length-1); return `[${res}]`; }; /** * Decodes your encoded data to tree. * * @param {string} data * @return {TreeNode} */ var deserialize = function(data) { //"[]" if(data.length <= 2) { return null; } const nodes = data.substring(1, data.length-1).split(','); const root = new TreeNode(parseInt(nodes.shift())); const queue = [root]; while(queue.length){ const cur = queue.shift(); const leftVal = nodes.shift(); if(leftVal !== "#"){ cur.left = new TreeNode(leftVal); queue.push(cur.left); } const rightVal = nodes.shift(); if(rightVal !== "#"){ cur.right = new TreeNode(rightVal); queue.push(cur.right); } } return root; }; /** * Your functions will be called as such: * deserialize(serialize(root)); */
时间复杂度: O(N)
空间复杂度:O(N)
易错:最后一个","需要单独去掉。