Skip to content

Commit 69336d0

Browse files
refactor 449
1 parent a8e6657 commit 69336d0

File tree

2 files changed

+155
-46
lines changed

2 files changed

+155
-46
lines changed

src/main/java/com/fishercoder/solutions/_449.java

+136-41
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,152 @@
66
import java.util.Queue;
77

88
/**
9-
* Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
10-
11-
Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.
12-
13-
The encoded string should be as compact as possible.
9+
* 449. Serialize and Deserialize BST
10+
*
11+
* Serialization is the process of converting a data structure or
12+
* object into a sequence of bits so that it can be stored in a file or memory buffer,
13+
* or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
14+
*
15+
* Design an algorithm to serialize and deserialize a binary search tree.
16+
* There is no restriction on how your serialization/deserialization algorithm should work.
17+
* You just need to ensure that a binary search tree can be serialized to a string and this
18+
* string can be deserialized to the original tree structure.
19+
* The encoded string should be as compact as possible.
1420
1521
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
1622
*/
23+
1724
public class _449 {
1825

19-
// Encodes a tree to a single string.
20-
public String serialize(TreeNode root) {
21-
Queue<TreeNode> queue = new LinkedList<>();
22-
StringBuilder stringBuilder = new StringBuilder();
23-
if (root == null) return stringBuilder.toString();
24-
queue.offer(root);
25-
while (!queue.isEmpty()) {
26-
int size = queue.size();
27-
for (int i = 0; i < size; i++) {
26+
public static class Solution1 {
27+
/**Preorder
28+
* Reference: https://discuss.leetcode.com/topic/97922/pre-or-post-order-with-only-keeping-one-bound-beat-98-and-95*/
29+
30+
// Encodes a tree to a single string.
31+
public String serialize(TreeNode root) {
32+
if (root == null) return null;
33+
StringBuilder stringBuilder = new StringBuilder();
34+
return serialize(root, stringBuilder);
35+
}
36+
37+
private String serialize(TreeNode root, StringBuilder stringBuilder) {
38+
if (root == null) {
39+
return null;
40+
}
41+
stringBuilder.append(root.val).append(" ");
42+
serialize(root.left, stringBuilder);
43+
serialize(root.right, stringBuilder);
44+
return stringBuilder.toString();
45+
}
46+
47+
// Decodes your encoded data to tree.
48+
public TreeNode deserialize(String data) {
49+
if (data == null || data.length() == 0) {
50+
return null;
51+
}
52+
String[] values = data.split(" ");
53+
int[] index = new int[]{0};/**TODO: Why must use an int array, instead of just an int?*/
54+
return deserialize(values, index, Integer.MAX_VALUE);
55+
}
56+
57+
private TreeNode deserialize(String[] values, int[] index, int maxValue) {
58+
if (index[0] >= values.length || Integer.valueOf(values[index[0]]) >= maxValue) {
59+
return null;
60+
}
61+
TreeNode root = new TreeNode(Integer.valueOf(values[index[0]++]));
62+
root.left = deserialize(values, index, root.val);
63+
root.right = deserialize(values, index, maxValue);
64+
return root;
65+
}
66+
}
67+
68+
public static class Solution2 {
69+
/**Postorder
70+
* Reference: https://discuss.leetcode.com/topic/97922/pre-or-post-order-with-only-keeping-one-bound-beat-98-and-95*/
71+
72+
public String serialize(TreeNode root) {
73+
if (root == null) {
74+
return null;
75+
}
76+
StringBuilder sb = new StringBuilder();
77+
return serialize(root, sb);
78+
}
79+
80+
private String serialize(TreeNode root, StringBuilder sb) {
81+
if (root == null) {
82+
return null;
83+
}
84+
serialize(root.left, sb);
85+
serialize(root.right, sb);
86+
sb.append(root.val).append(" ");
87+
return sb.toString();
88+
}
89+
90+
// Decodes your encoded data to tree.
91+
public TreeNode deserialize(String data) {
92+
if (data == null || data.length() == 0) {
93+
return null;
94+
}
95+
String[] values = data.split(" ");
96+
int[] index = new int[]{values.length-1};/**TODO: This is not just one element any more like in the preorder solution above*/
97+
return deserialize(values, index, Integer.MIN_VALUE);
98+
}
99+
100+
private TreeNode deserialize(String[] values, int[] index, int minValue) {
101+
if (index[0] < 0 || Integer.valueOf(values[index[0]]) < minValue) {
102+
return null;
103+
}
104+
TreeNode root = new TreeNode(Integer.valueOf(values[index[0]--]));
105+
root.right = deserialize(values, index, root.val);
106+
root.left = deserialize(values, index, minValue);
107+
return root;
108+
}
109+
}
110+
111+
public static class Solution3 {
112+
/**This is a generic solution that applies to both BT and BST.*/
113+
114+
// Encodes a tree to a single string.
115+
public String serialize(TreeNode root) {
116+
Queue<TreeNode> queue = new LinkedList<>();
117+
StringBuilder stringBuilder = new StringBuilder();
118+
if (root == null) return stringBuilder.toString();
119+
queue.offer(root);
120+
while (!queue.isEmpty()) {
121+
int size = queue.size();
122+
for (int i = 0; i < size; i++) {
123+
TreeNode curr = queue.poll();
124+
if (curr == null) {
125+
stringBuilder.append("# ");
126+
} else {
127+
stringBuilder.append(curr.val + " ");
128+
queue.offer(curr.left);
129+
queue.offer(curr.right);
130+
}
131+
}
132+
}
133+
return stringBuilder.toString();
134+
}
135+
136+
// Decodes your encoded data to tree.
137+
public TreeNode deserialize(String data) {
138+
if (data == null || data.length() == 0) return null;
139+
String[] nodes = data.split(" ");
140+
TreeNode root = new TreeNode(Integer.valueOf(nodes[0]));
141+
Queue<TreeNode> queue = new LinkedList<>();
142+
queue.offer(root);
143+
for (int i = 1; i < nodes.length; i++) {
28144
TreeNode curr = queue.poll();
29-
if (curr == null) {
30-
stringBuilder.append("# ");
31-
} else {
32-
stringBuilder.append(curr.val + " ");
145+
if (!nodes[i].equals("#")) {
146+
curr.left = new TreeNode(Integer.valueOf(nodes[i]));
33147
queue.offer(curr.left);
148+
}
149+
if (!nodes[++i].equals("#")) {
150+
curr.right = new TreeNode(Integer.valueOf(nodes[i]));
34151
queue.offer(curr.right);
35152
}
36153
}
154+
return root;
37155
}
38-
return stringBuilder.toString();
39-
}
40-
41-
// Decodes your encoded data to tree.
42-
public TreeNode deserialize(String data) {
43-
if (data == null || data.length() == 0) return null;
44-
String[] nodes = data.split(" ");
45-
TreeNode root = new TreeNode(Integer.valueOf(nodes[0]));
46-
Queue<TreeNode> queue = new LinkedList<>();
47-
queue.offer(root);
48-
for (int i = 1; i < nodes.length; i++) {
49-
TreeNode curr = queue.poll();
50-
if (!nodes[i].equals("#")) {
51-
curr.left = new TreeNode(Integer.valueOf(nodes[i]));
52-
queue.offer(curr.left);
53-
}
54-
if (!nodes[++i].equals("#")) {
55-
curr.right = new TreeNode(Integer.valueOf(nodes[i]));
56-
queue.offer(curr.right);
57-
}
58-
}
59-
return root;
60156
}
61-
62157
}

src/test/java/com/fishercoder/_449Test.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
import static junit.framework.Assert.assertEquals;
1010

1111
public class _449Test {
12-
private static _449 test;
13-
private static TreeNode actualRoot;
12+
private static _449.Solution1 solution1;
13+
private static _449.Solution2 solution2;
14+
private static _449.Solution3 solution3;
1415
private static TreeNode expectedRoot;
1516

1617
@BeforeClass
1718
public static void setup(){
18-
test = new _449();
19+
solution1 = new _449.Solution1();
20+
solution2 = new _449.Solution2();
21+
solution3 = new _449.Solution3();
1922
}
2023

2124
@Before
@@ -28,7 +31,18 @@ public void test1(){
2831
expectedRoot.left = new TreeNode(1);
2932
expectedRoot.right = new TreeNode(4);
3033
expectedRoot.left.right = new TreeNode(2);
31-
actualRoot = test.deserialize(test.serialize(expectedRoot));
32-
assertEquals(expectedRoot.toString(), actualRoot.toString());
34+
assertEquals(expectedRoot.toString(), solution1.deserialize(solution1.serialize(expectedRoot)).toString());
35+
assertEquals(expectedRoot.toString(), solution2.deserialize(solution2.serialize(expectedRoot)).toString());
36+
assertEquals(expectedRoot.toString(), solution3.deserialize(solution3.serialize(expectedRoot)).toString());
37+
}
38+
39+
@Test
40+
public void test2(){
41+
expectedRoot = new TreeNode(2);
42+
expectedRoot.left = new TreeNode(1);
43+
expectedRoot.right = new TreeNode(3);
44+
assertEquals(expectedRoot.toString(), solution1.deserialize(solution1.serialize(expectedRoot)).toString());
45+
assertEquals(expectedRoot.toString(), solution2.deserialize(solution2.serialize(expectedRoot)).toString());
46+
assertEquals(expectedRoot.toString(), solution3.deserialize(solution3.serialize(expectedRoot)).toString());
3347
}
3448
}

0 commit comments

Comments
 (0)