449. 序列化和反序列化二叉搜索树 - Kotlin 深度优先搜索
Problem: 449. 序列化和反序列化二叉搜索树
思路
如果按照中序遍历打印二叉搜索树,会直接打印出顺序序列,这时该树的根节点隐藏在序列中间,整个序列的组成为:左子树序列+根节点+右子树序列,由于整个数组都是顺序的,我们无法分辨出序列的哪个是根节点。由于序列必然由这三个部分组成,关键在于按什么顺序组成这个序列。
我们已经知道,左子树中的任意一个节点都必然小于根节点,右子树的任意一个节点都必然大于根节点,那么我们实际上是可以将左子树序列和右子树序列相邻放置的,当遍历指针指向元素从小于根节点变为大于根节点时,即说明左子树的序列已经结束
那么我们直接约定:序列的第一个元素为根节点即可
每次遍历序列时由序列的第一个元素构建根节点,然后令指针i++直至指向元素大于根节点,则此时seq[1..i-1]
即为左子树序列,seq[i..seq.size-1]
即为右子树序列,递归上述步骤即可
复杂度
Code
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
| class Codec() { fun serialize(root: TreeNode?): String = if (root == null) "" else root.`val`.toString() + (if (root.left != null) "," + serialize(root.left) else "") + (if (root.right != null) "," + serialize(root.right) else "")
fun deserialize(data: String): TreeNode? = if (data == "") null else deserialize(data.split(",").toTypedArray())
fun deserialize(data: Array<String>): TreeNode? { if (data.isEmpty()) { return null } val root = TreeNode(data[0].toInt()) var i = 1 while (i < data.size && data[i].toInt() < root.`val`) { i++ } root.left = deserialize(data.sliceArray(1 until i)) root.right = deserialize(data.sliceArray(i until data.size)) return root } }
|