剑指 Offer II 048. 序列化与反序列化二叉树
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
示例 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
注意:本题与主站 297 题相同:https://leetcode.cn/problems/serialize-and-deserialize-binary-tree/
原站题解
javascript 解法, 执行用时: 932 ms, 内存消耗: 51.8 MB, 提交时间: 2023-01-12 10:23:26
/** * 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) { return rserialize(root, ''); }; /** * Decodes your encoded data to tree. * * @param {string} data * @return {TreeNode} */ var deserialize = function(data) { const dataArray = data.split(","); return rdeserialize(dataArray); }; const rserialize = (root, str) => { if (root === null) { str += "None,"; } else { str += root.val + '' + ","; str = rserialize(root.left, str); str = rserialize(root.right, str); } return str; } const rdeserialize = (dataList) => { if (dataList[0] === "None") { dataList.shift(); return null; } const root = new TreeNode(parseInt(dataList[0])); dataList.shift(); root.left = rdeserialize(dataList); root.right = rdeserialize(dataList); return root; } /** * Your functions will be called as such: * deserialize(serialize(root)); */
javascript 解法, 执行用时: 100 ms, 内存消耗: 56.6 MB, 提交时间: 2023-01-12 10:22:38
/** * 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 == null) { return "X"; } const left = "(" + serialize(root.left) + ")"; const right = "(" + serialize(root.right) + ")"; return left + root.val + right; }; /** * Decodes your encoded data to tree. * * @param {string} data * @return {TreeNode} */ var deserialize = function(data) { const ptr = [0]; return parse(data, ptr); }; const parse = (data, ptr) => { if (data[ptr[0]] === 'X') { ++ptr[0]; return null; } let cur = new TreeNode(0); cur.left = parseSubtree(data, ptr); cur.val = parseInt2(data, ptr); cur.right = parseSubtree(data, ptr); return cur; } const parseSubtree = (data, ptr) => { ++ptr[0]; // 跳过左括号 const subtree = parse(data, ptr); ++ptr[0]; // 跳过右括号 return subtree; } const parseInt2 = (data, ptr) => { let x = 0, sgn = 1; if (isNaN(Number(data[ptr[0]]))) { sgn = -1; ++ptr[0]; } while (!isNaN(Number(data[ptr[0]]))) { x = x * 10 + data[ptr[0]++].charCodeAt() - '0'.charCodeAt(); } return x * sgn; } /** * Your functions will be called as such: * deserialize(serialize(root)); */
java 解法, 执行用时: 20 ms, 内存消耗: 43.4 MB, 提交时间: 2023-01-12 10:21:27
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { public String serialize(TreeNode root) { if (root == null) { return "X"; } String left = "(" + serialize(root.left) + ")"; String right = "(" + serialize(root.right) + ")"; return left + root.val + right; } public TreeNode deserialize(String data) { int[] ptr = {0}; return parse(data, ptr); } public TreeNode parse(String data, int[] ptr) { if (data.charAt(ptr[0]) == 'X') { ++ptr[0]; return null; } TreeNode cur = new TreeNode(0); cur.left = parseSubtree(data, ptr); cur.val = parseInt(data, ptr); cur.right = parseSubtree(data, ptr); return cur; } public TreeNode parseSubtree(String data, int[] ptr) { ++ptr[0]; // 跳过左括号 TreeNode subtree = parse(data, ptr); ++ptr[0]; // 跳过右括号 return subtree; } public int parseInt(String data, int[] ptr) { int x = 0, sgn = 1; if (!Character.isDigit(data.charAt(ptr[0]))) { sgn = -1; ++ptr[0]; } while (Character.isDigit(data.charAt(ptr[0]))) { x = x * 10 + data.charAt(ptr[0]++) - '0'; } return x * sgn; } } // Your Codec object will be instantiated and called as such: // Codec ser = new Codec(); // Codec deser = new Codec(); // TreeNode ans = deser.deserialize(ser.serialize(root));
java 解法, 执行用时: 112 ms, 内存消耗: 44.5 MB, 提交时间: 2023-01-12 10:20:59
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { public String serialize(TreeNode root) { return rserialize(root, ""); } public TreeNode deserialize(String data) { String[] dataArray = data.split(","); List<String> dataList = new LinkedList<String>(Arrays.asList(dataArray)); return rdeserialize(dataList); } public String rserialize(TreeNode root, String str) { if (root == null) { str += "None,"; } else { str += str.valueOf(root.val) + ","; str = rserialize(root.left, str); str = rserialize(root.right, str); } return str; } public TreeNode rdeserialize(List<String> dataList) { if (dataList.get(0).equals("None")) { dataList.remove(0); return null; } TreeNode root = new TreeNode(Integer.valueOf(dataList.get(0))); dataList.remove(0); root.left = rdeserialize(dataList); root.right = rdeserialize(dataList); return root; } } // Your Codec object will be instantiated and called as such: // Codec ser = new Codec(); // Codec deser = new Codec(); // TreeNode ans = deser.deserialize(ser.serialize(root));
golang 解法, 执行用时: 8 ms, 内存消耗: 6.3 MB, 提交时间: 2023-01-12 10:20:02
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ type Codec struct{} func Constructor() (_ Codec) { return } func (Codec) serialize(root *TreeNode) string { sb := &strings.Builder{} var dfs func(*TreeNode) dfs = func(node *TreeNode) { if node == nil { sb.WriteString("null,") return } sb.WriteString(strconv.Itoa(node.Val)) sb.WriteByte(',') dfs(node.Left) dfs(node.Right) } dfs(root) return sb.String() } func (Codec) deserialize(data string) *TreeNode { sp := strings.Split(data, ",") var build func() *TreeNode build = func() *TreeNode { if sp[0] == "null" { sp = sp[1:] return nil } val, _ := strconv.Atoi(sp[0]) sp = sp[1:] return &TreeNode{val, build(), build()} } return build() } /** * Your Codec object will be instantiated and called as such: * ser := Constructor(); * deser := Constructor(); * data := ser.serialize(root); * ans := deser.deserialize(data); */
golang 解法, 执行用时: 12 ms, 内存消耗: 7.6 MB, 提交时间: 2023-01-12 10:19:31
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ type Codec struct{} func Constructor() (_ Codec) { return } func (c Codec) serialize(root *TreeNode) string { if root == nil { return "X" } left := "(" + c.serialize(root.Left) + ")" right := "(" + c.serialize(root.Right) + ")" return left + strconv.Itoa(root.Val) + right } func (Codec) deserialize(data string) *TreeNode { var parse func() *TreeNode parse = func() *TreeNode { if data[0] == 'X' { data = data[1:] return nil } node := &TreeNode{} data = data[1:] // 跳过左括号 node.Left = parse() data = data[1:] // 跳过右括号 i := 0 for data[i] == '-' || '0' <= data[i] && data[i] <= '9' { i++ } node.Val, _ = strconv.Atoi(data[:i]) data = data[i:] data = data[1:] // 跳过左括号 node.Right = parse() data = data[1:] // 跳过右括号 return node } return parse() } /** * Your Codec object will be instantiated and called as such: * ser := Constructor(); * deser := Constructor(); * data := ser.serialize(root); * ans := deser.deserialize(data); */