二叉搜索树的序列化和反序列化。题意跟297题很接近,唯一的不同是297题是对普通的二叉树做操作,用层序遍历;本题是用到前序遍历。
序列化没什么可说的,用前序遍历preorder,会得到一个有序的数组。反序列化需要先拿到queue中的第一个节点,此节点为树的根节点;对于之后的所有节点,需要判断他们到底是大于还是小于根节点,将较小的节点用另一个queue存放,这样左右子树上的节点就可以被分开了。用这样的递归完成树的构建。
时间O(n)
空间O(n),序列化用到了stack,反序列化用到了queue和递归的栈空间
Java实现
1 public class Codec { 2 3 // Encodes a tree to a single string. 4 public String serialize(TreeNode root) { 5 if (root == null) 6 return ""; 7 StringBuilder res = new StringBuilder(); 8 Stack<TreeNode> stack = new Stack<>(); 9 stack.push(root); 10 while (!stack.isEmpty()) { 11 TreeNode cur = stack.pop(); 12 res.append(cur.val + " "); 13 if (cur.right != null) { 14 stack.push(cur.right); 15 } 16 if (cur.left != null) { 17 stack.push(cur.left); 18 } 19 } 20 return res.toString(); 21 } 22 23 // Decodes your encoded data to tree. 24 public TreeNode deserialize(String data) { 25 if (data == "") 26 return null; 27 String[] str = data.split(" "); 28 Queue<Integer> queue = new LinkedList<>(); 29 for (String s : str) { 30 queue.offer(Integer.parseInt(s)); 31 } 32 return getNode(queue); 33 } 34 35 public TreeNode getNode(Queue<Integer> queue) { 36 if (queue.isEmpty()) 37 return null; 38 TreeNode root = new TreeNode(queue.poll()); 39 Queue<Integer> smallerQ = new LinkedList<>(); 40 while (!queue.isEmpty() && queue.peek() < root.val) { 41 smallerQ.offer(queue.poll()); 42 } 43 root.left = getNode(smallerQ); 44 root.right = getNode(queue); 45 return root; 46 } 47 } 48 49 // Your Codec object will be instantiated and called as such: 50 // Codec codec = new Codec(); 51 // codec.deserialize(codec.serialize(root));
JavaScript实现
1 /** 2 * Encodes a tree to a single string. 3 * 4 * @param {TreeNode} root 5 * @return {string} 6 */ 7 var serialize = function (root) { 8 let preorder = []; 9 let dfs = function (node) { 10 if (node == null) return; 11 preorder.push(node.val); 12 dfs(node.left); 13 dfs(node.right); 14 } 15 dfs(root); 16 return preorder.join(','); 17 }; 18 19 /** 20 * Decodes your encoded data to tree. 21 * 22 * @param {string} data 23 * @return {TreeNode} 24 */ 25 var deserialize = function (data) { 26 if (data == '') return null; 27 let preorder = data.split(','); 28 let recur = function (lower, upper) { 29 if (Number(preorder[0]) < lower || Number(preorder[0]) > upper) { 30 return null; 31 } 32 if (preorder.length == 0) return null; 33 let root = new TreeNode(preorder.shift()); 34 root.left = recur(lower, root.val); 35 root.right = recur(root.val, upper); 36 return root; 37 } 38 return recur(-Infinity, Infinity); 39 }; 40 41 /** 42 * Your functions will be called as such: 43 * deserialize(serialize(root)); 44 */