-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paths0297_serialize_and_deserialize_binary_tree.go
More file actions
134 lines (114 loc) · 2.75 KB
/
s0297_serialize_and_deserialize_binary_tree.go
File metadata and controls
134 lines (114 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
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.
Design an algorithm to serialize and deserialize a binary tree. There is no
restriction on how your
serialization/deserialization algorithm should work. You just need to ensure
that a binary tree can be
serialized to a string and this string can be deserialized to the original tree
structure.
Clarification: The input/output format is the same as how LeetCode serializes a
binary tree.
You do not necessarily need to follow this format, so please be creative and
come up with different
approaches yourself.
*/
package solutions
import (
"fmt"
"strconv"
"strings"
)
//nolint:revive // it's ok
type Codec struct{}
// NewCodec should call Constructor to pass LeetCode tests
func NewCodec() Codec {
return Codec{}
}
// Serializes a tree to a single string.
func (c *Codec) serialize(root *TreeNode) string {
return fmt.Sprintf("[%s]", strings.Join(leveDfs([]*TreeNode{root}), ","))
}
// Deserializes your encoded data to tree.
func (c *Codec) deserialize(data string) *TreeNode {
if len(data) < 3 {
return nil
}
return buildTreeFromString(data)
}
func buildTreeFromString(s string) *TreeNode {
s = strings.TrimPrefix(s, "[")
s = strings.TrimSuffix(s, "]")
xs := strings.Split(s, ",")
rootVal, _ := strconv.Atoi(xs[0])
root := &TreeNode{rootVal, nil, nil}
levelBfsBuild([]*TreeNode{root}, xs[1:])
return root
}
func levelBfsBuild(q []*TreeNode, all []string) {
if len(all) == 0 {
return
}
var nextQ []*TreeNode
for len(q) > 0 {
n := q[0]
q = q[1:]
if n == nil {
continue
}
l, r := all[0], all[1]
all = all[2:]
lVal, lErr := strconv.Atoi(l)
rVal, rErr := strconv.Atoi(r)
if lErr != nil {
nextQ = append(nextQ, nil)
} else {
left := &TreeNode{
lVal,
nil,
nil,
}
n.Left = left
nextQ = append(nextQ, left)
}
if rErr != nil {
nextQ = append(nextQ, nil)
} else {
right := &TreeNode{
rVal,
nil,
nil,
}
n.Right = right
nextQ = append(nextQ, right)
}
}
levelBfsBuild(nextQ, all)
}
func leveDfs(q []*TreeNode) []string {
if len(q) == 0 {
return []string{}
}
var nextQ []*TreeNode
var level []string
var isLevelValid bool
for len(q) > 0 {
n := q[0]
q = q[1:]
if n == nil {
level = append(level, "null")
continue
}
level = append(level, strconv.Itoa(n.Val))
isLevelValid = true
nextQ = append(nextQ, n.Left, n.Right)
}
if !isLevelValid {
level = []string{}
}
return append(level, leveDfs(nextQ)...)
}