其他分享
首页 > 其他分享> > LeetCode刷题——449. 序列化和反序列化二叉搜索树

LeetCode刷题——449. 序列化和反序列化二叉搜索树

作者:互联网

题目描述

序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。

设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。

编码的字符串应尽可能紧凑。

 

示例 1:

输入:root = [2,1,3]
输出:[2,1,3]
示例 2:

输入:root = []
输出:[]
 

提示:

树中节点数范围是 [0, 104]
0 <= Node.val <= 104
题目数据 保证 输入的树是一棵二叉搜索树。

方法一:后序遍历

思路

给定一棵二叉树的「先序遍历」和「中序遍历」可以恢复这颗二叉树。给定一棵二叉树的「后序遍历」和「中序遍历」也可以恢复这颗二叉树。而对于二叉搜索树,给定「先序遍历」或者「后序遍历」,对其经过排序即可得到「中序遍历」。因此,仅对二叉搜索树做「先序遍历」或者「后序遍历」,即可达到序列化和反序列化的要求。此题解采用「后序遍历」的方法。

序列化时,只需要对二叉搜索树进行后序遍历,再将数组编码成字符串即可。

反序列化时,需要先将字符串解码成后序遍历的数组。在将后序遍历的数组恢复成二叉搜索树时,不需要先排序得到中序遍历的数组再根据中序和后序遍历的数组来恢复二叉树,而可以根据有序性直接由后序遍历的数组恢复二叉搜索树。后序遍历得到的数组中,根结点的值位于数组末尾,左子树的节点均小于根节点的值,右子树的节点均大于根节点的值,可以根据这些性质设计递归函数恢复二叉搜索树。

代码

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 public class Codec {
11 
12     // Encodes a tree to a single string.
13     public String serialize(TreeNode root) {
14         if (root == null) {
15             return null;
16         }
17         List<Integer> list = new ArrayList<>();
18         postOrder(root, list);
19         String s = list.toString();
20         return s.substring(1, s.length() - 1);
21     }
22 
23     /**
24     后续遍历
25      */
26     public void postOrder(TreeNode root, List<Integer> list) {
27         if (root == null) {
28             return;
29         }
30         postOrder(root.left, list);
31         postOrder(root.right, list);
32         list.add(root.val);
33     }
34 
35     // Decodes your encoded data to tree.
36     public TreeNode deserialize(String data) {
37         if (data == null) {
38             return null;
39         }
40         Deque<Integer> stack = new ArrayDeque<>();
41         String[] nodeArr = data.split(", ");
42         for (int i = 0; i < nodeArr.length; i++) {
43             stack.push(Integer.parseInt(nodeArr[i]));
44         }
45         return deserialize(Integer.MIN_VALUE, Integer.MAX_VALUE, stack);
46     }
47 
48     public TreeNode deserialize(int lower, int higher, Deque<Integer> stack) {
49         // 后面两个条件判断是用于区分左右孩子(即左右孩子节点的边界)
50         if (stack.isEmpty() || stack.peek() <= lower || stack.peek() >= higher) {
51             return null;
52         }
53         int val = stack.pop();
54         TreeNode root = new TreeNode(val);
55         root.right = deserialize(val, higher, stack);
56         root.left = deserialize(lower, val, stack);
57         return root;
58     }
59 }
60 
61 // Your Codec object will be instantiated and called as such:
62 // Codec ser = new Codec();
63 // Codec deser = new Codec();
64 // String tree = ser.serialize(root);
65 // TreeNode ans = deser.deserialize(tree);
66 // return ans;

 

标签:449,遍历,TreeNode,后序,二叉,序列化,root,LeetCode
来源: https://www.cnblogs.com/pengsay/p/16258094.html