序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
示例 1:
输入:root = [2,1,3]
输出:[2,1,3]
示例 2:
输入:root = []
输出:[]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/serialize-and-deserialize-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:递归,时间和空间复杂度O(N)
- public class Codec {
- // Encodes a tree to a single string.
- public String serialize(TreeNode root) {
- StringBuilder sb = new StringBuilder();
- traverse(root, sb);
- return sb.toString();
- }
-
- final String SEP = ",";
- private void traverse(TreeNode root, StringBuilder sb) {
- if (root == null) {
- return;
- }
- sb.append(root.val).append(SEP);
- traverse(root.left, sb);
- traverse(root.right, sb);
- }
-
- // Decodes your encoded data to tree.
- public TreeNode deserialize(String data) {
- if (data == null || data.isEmpty()) {
- return null;
- }
- List
list = new ArrayList<>(); - for (String node : data.split(SEP)) {
- list.add(Integer.parseInt(node));
- }
- return deserialize(list, 0, list.size() - 1);
- }
-
- private TreeNode deserialize(List
list, int lo, int hi) { - if (lo > hi) {
- return null;
- }
- TreeNode root = new TreeNode(list.get(lo));
- int k = lo + 1;
- //利用BST特性,左子树小于根节点值,找到分界点
- while (k <= hi && list.get(k) < list.get(lo)) {
- k++;
- }
- root.left = deserialize(list, lo + 1, k - 1);
- root.right = deserialize(list, k, hi);
- return root;
- }
-
- }
方法二:利用栈遍历,时间和空间复杂度O(N)
- public class Codec {
- // Encodes a tree to a single string.
- public String serialize(TreeNode root) {
- StringBuilder sb = new StringBuilder();
- traverse(root, sb);
- return sb.toString();
- }
-
- final String SEP = ",";
- private void traverse(TreeNode root, StringBuilder sb) {
- if (root == null) {
- return;
- }
- sb.append(root.val).append(SEP);
- traverse(root.left, sb);
- traverse(root.right, sb);
- }
-
- // Decodes your encoded data to tree.
- public TreeNode deserialize(String data) {
- if (data == null || data.isEmpty()) {
- return null;
- }
- String[] preOrder = data.split(SEP);
- TreeNode root = new TreeNode(Integer.parseInt(preOrder[0]));
- Stack
stack = new Stack<>(); - stack.push(root);
- for (int i = 1; i < preOrder.length; i++) {
- int val = Integer.parseInt(preOrder[i]);
- TreeNode node = new TreeNode(val);
- //小于栈顶元素的值,说明应该在栈顶元素的左子树
- if (stack.peek().val > val) {
- stack.peek().left = node;
- } else {
- //大于栈顶元素的值,我们要找到当前元素的父节点
- TreeNode parent = stack.peek();
- //栈从栈底到栈顶是递减的
- while (!stack.isEmpty() && stack.peek().val < val) {
- parent = stack.pop();
- }
- parent.right = node;
- }
- stack.push(node);
- }
- return root;
- }
- }