|
| 1 | +""" |
| 2 | +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. |
| 3 | +
|
| 4 | +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. |
| 5 | +
|
| 6 | +Example: |
| 7 | +
|
| 8 | +You may serialize the following tree: |
| 9 | +
|
| 10 | + 1 |
| 11 | + / \ |
| 12 | + 2 3 |
| 13 | + / \ |
| 14 | + 4 5 |
| 15 | +
|
| 16 | +as "[1,2,3,null,null,4,5]" |
| 17 | +Clarification: The above 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. |
| 18 | +
|
| 19 | +Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. |
| 20 | +
|
| 21 | +
|
| 22 | +二叉树的“结”构与解构,在很久以前的一个同样的思路中用了 JSON,因为那个没有标明字符串的输出形式,所以用JSON可以直接用字典来写明每个点的 left, right, val。 |
| 23 | +
|
| 24 | +Leetcode中的这个需要是列表形式的,所以不用 JSON 的思路了。 |
| 25 | +
|
| 26 | +
|
| 27 | +按照这个形式,可以以 层 来分级。 |
| 28 | +
|
| 29 | +也就是 BFS 的思路: |
| 30 | +
|
| 31 | + 1 |
| 32 | + / \ |
| 33 | + 2 3 |
| 34 | + / \ |
| 35 | + 4 5 |
| 36 | +
|
| 37 | +第一层是 |
| 38 | +1 |
| 39 | +第二层是 |
| 40 | +2 3 |
| 41 | +第三层是 |
| 42 | +None None 4 5 |
| 43 | +第四层全是 None。 |
| 44 | +
|
| 45 | +serialize 的话比较好写: |
| 46 | +
|
| 47 | +如果节点不为 None,把val加入到result中,left和right都加到下一层节点里。 |
| 48 | + 为 None 的话就加 None 到result里。 |
| 49 | +
|
| 50 | +最后处理下尾部的None即可。 |
| 51 | +
|
| 52 | +deserialize 的话: |
| 53 | +目前也是同样的思路 |
| 54 | +1 2 4 8 16 这样的递增,除了最后一层肯定是可以满满的排满的。 |
| 55 | +
|
| 56 | +一个是 roots,上一层的roots,一个是nodes,要给roots加 right 和 left 的nodes。 |
| 57 | +
|
| 58 | +有一个点需要注意: |
| 59 | +上一层serialize之后的 None 的处理,要处理成 'null',否则 Leetcode 不通过。 |
| 60 | +
|
| 61 | +beat 62% |
| 62 | +
|
| 63 | +测试地址: |
| 64 | +https://leetcode.com/problems/serialize-and-deserialize-binary-tree/description/ |
| 65 | +
|
| 66 | +--- |
| 67 | +
|
| 68 | +如果只为了通过测试: |
| 69 | +serialize 直接 return root |
| 70 | +deserialize 直接 return data... |
| 71 | +
|
| 72 | +因为它的测试是 |
| 73 | +# codec = Codec() |
| 74 | +# codec.deserialize(codec.serialize(root)) |
| 75 | +
|
| 76 | +排在最前面的几个是这样做的 = =... |
| 77 | +
|
| 78 | +前面的大神写的也有很厉害的: |
| 79 | +class Codec: |
| 80 | +
|
| 81 | + def serialize(self, root): |
| 82 | + '''Encodes a tree to a single string. |
| 83 | + |
| 84 | + :type root: TreeNode |
| 85 | + :rtype: str |
| 86 | + ''' |
| 87 | + def doit(node): |
| 88 | + if node: |
| 89 | + vals.append(node.val) |
| 90 | + doit(node.left) |
| 91 | + doit(node.right) |
| 92 | + else: |
| 93 | + vals.append('#') |
| 94 | + |
| 95 | + vals = [] |
| 96 | + doit(root) |
| 97 | + return vals |
| 98 | +
|
| 99 | +
|
| 100 | + def deserialize(self, data): |
| 101 | + '''Decodes your encoded data to tree. |
| 102 | + |
| 103 | + :type data: str |
| 104 | + :rtype: TreeNode |
| 105 | + ''' |
| 106 | + def doit(): |
| 107 | + val = next(vals) |
| 108 | + if val == '#': |
| 109 | + return None |
| 110 | + else: |
| 111 | + node = TreeNode(val) |
| 112 | + node.left = doit() |
| 113 | + node.right = doit() |
| 114 | + return node |
| 115 | + |
| 116 | + vals = iter(data) |
| 117 | + return doit() |
| 118 | +
|
| 119 | +思路非常流畅,看过之后也是恍然大悟的感觉,比上面的这个思路要快 20ms 左右。 |
| 120 | +
|
| 121 | +""" |
| 122 | +# Definition for a binary tree node. |
| 123 | +# class TreeNode(object): |
| 124 | +# def __init__(self, x): |
| 125 | +# self.val = x |
| 126 | +# self.left = None |
| 127 | +# self.right = None |
| 128 | + |
| 129 | +class Codec: |
| 130 | + |
| 131 | + def serialize(self, root): |
| 132 | + """Encodes a tree to a single string. |
| 133 | + |
| 134 | + :type root: TreeNode |
| 135 | + :rtype: str |
| 136 | + """ |
| 137 | + if not root: |
| 138 | + return None |
| 139 | + |
| 140 | + result = [] |
| 141 | + |
| 142 | + def _serialize(roots): |
| 143 | + _next = [] |
| 144 | + for i in roots: |
| 145 | + if i: |
| 146 | + result.append(i.val) |
| 147 | + _next.append(i.left) |
| 148 | + _next.append(i.right) |
| 149 | + |
| 150 | + else: |
| 151 | + result.append(None) |
| 152 | + |
| 153 | + return _next |
| 154 | + |
| 155 | + base = _serialize([root]) |
| 156 | + |
| 157 | + while any(base): |
| 158 | + base = _serialize(base) |
| 159 | + |
| 160 | + while 1: |
| 161 | + if result[-1] == None: |
| 162 | + result.pop() |
| 163 | + else: |
| 164 | + break |
| 165 | + |
| 166 | + return str(result) |
| 167 | + |
| 168 | + |
| 169 | + def deserialize(self, data): |
| 170 | + """Decodes your encoded data to tree. |
| 171 | + |
| 172 | + :type data: str |
| 173 | + :rtype: TreeNode |
| 174 | + """ |
| 175 | + |
| 176 | + if not data: |
| 177 | + return [] |
| 178 | + |
| 179 | + data = data[1:-1].split(',') |
| 180 | + |
| 181 | + root = TreeNode(data[0]) |
| 182 | + |
| 183 | + length = 2 |
| 184 | + data.pop(0) |
| 185 | + leaves = [root] |
| 186 | + |
| 187 | + def _deserialize(roots, nodes): |
| 188 | + _next = [] |
| 189 | + for i in roots: |
| 190 | + if not i: |
| 191 | + continue |
| 192 | + |
| 193 | + if nodes: |
| 194 | + val = nodes.pop(0) |
| 195 | + if val == ' None': |
| 196 | + val = 'null' |
| 197 | + else: |
| 198 | + val = int(val) |
| 199 | + |
| 200 | + i.left = TreeNode(val) |
| 201 | + _next.append(i.left) |
| 202 | + |
| 203 | + if nodes: |
| 204 | + val = nodes.pop(0) |
| 205 | + if val == ' None': |
| 206 | + val = 'null' |
| 207 | + else: |
| 208 | + val = int(val) |
| 209 | + |
| 210 | + i.right = TreeNode(val) |
| 211 | + _next.append(i.right) |
| 212 | + return _next |
| 213 | + base = _deserialize(leaves, data[:length]) |
| 214 | + data = data[length:] |
| 215 | + length *= 2 |
| 216 | + while data: |
| 217 | + base = _deserialize(base, data[:length]) |
| 218 | + data = data[length:] |
| 219 | + length *= 2 |
| 220 | + return root |
| 221 | + |
| 222 | + |
| 223 | +# Your Codec object will be instantiated and called as such: |
| 224 | +# codec = Codec() |
| 225 | +# codec.deserialize(codec.serialize(root)) |
0 commit comments