题目

https://leetcode.com/problems/serialize-and-deserialize-bst/

题解

本题的难点在于 利用 BST 的性质

几个提示
  • 根据后序遍历BST性质,头结点是最后一个元素,且有一个分界,满足比头结点小的都在左边,比头结点大的都在右边
  • 本题满足条件(但是题目中没说)没有重复值
  • 要求你返回的树的形状不仅是 BST,而且要与输入完全相同。同样是 BST,注意以下两树的区别。它们中序序列相同,后序序列不同。
对比

一开始我想,这不就是序列化/反序列化一棵普通树吗?只不过给你的时候恰好是 BST。这和 297. Serialize and Deserialize Binary Tree 有什么不同?

再一想,不一样。利用二叉树的性质,可以将序列化结果简化,也就是本题说的 The encoded string should be as compact as possible. 编码的字符串应尽可能紧凑

参考左神算法书 P107 “二叉树的序列化和反序列化”,他在序列化一棵普通树的时候,利用了先序遍历的方式,用 # 记录空节点。而本题是 BST,其本身性质决定了不需要通过 # 记录空节点,也能进行 唯一结果的 序列化与反序列化。

附从错误思路到正确思路的草稿:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Codec {// Encodes a tree to a single string.public String serialize(TreeNode root) {if (root == null) return "";StringBuilder s = new StringBuilder();postOrder(root, s);return s.substring(0, s.length() - 1); // 移除末尾 ','}public void postOrder(TreeNode node, StringBuilder s) {if (node == null) return;postOrder(node.left, s);postOrder(node.right, s);s.append(node.val).append(",");}// Decodes your encoded data to tree.public TreeNode deserialize(String data) {if (data.equals("")) return null;String[] ss = data.split(",");int[] arr = new int[ss.length];for (int i = 0; i < ss.length; i++) {arr[i] = Integer.parseInt(ss[i]);}return buildBST(arr, 0, arr.length - 1);}// 根据后序遍历BST性质,头结点是最后一个元素,且有一个分界,满足比头结点小的都在左边,比头结点大的都在右边public TreeNode buildBST(int[] arr, int L, int R) {if (L > R) return null;TreeNode node = new TreeNode(arr[R]);// 找左右子树的分界点int M = L;while (arr[M] < arr[R]) {M++;}// M指向分界点右边第一个元素,本题缺隐含条件:没有重复值!node.left = buildBST(arr, L, M - 1);node.right = buildBST(arr, M, R - 1);return node;}
}// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// String tree = ser.serialize(root);
// TreeNode ans = deser.deserialize(tree);
// return ans;

可参考:左程云《程序员代码面试指南》根据后序数组重建搜索二叉树


package chapter_3_binarytreeproblem;public class Problem_14_PosArrayToBST {public static boolean isPostArray(int[] arr) {if (arr == null || arr.length == 0) {return false;}return isPost(arr, 0, arr.length - 1);}public static boolean isPost(int[] arr, int start, int end) {if (start == end) {return true;}int less = -1;int more = end;for (int i = start; i < end; i++) {if (arr[end] > arr[i]) {less = i;} else {more = more == end ? i : more;}}if (less == -1 || more == end) {return isPost(arr, start, end - 1);}if (less != more - 1) {return false;}return isPost(arr, start, less) && isPost(arr, more, end - 1);}public static class Node {public int value;public Node left;public Node right;public Node(int value) {this.value = value;}}public static Node posArrayToBST(int[] posArr) {if (posArr == null) {return null;}return posToBST(posArr, 0, posArr.length - 1);}public static Node posToBST(int[] posArr, int start, int end) {if (start > end) {return null;}Node head = new Node(posArr[end]);int less = -1;int more = end;for (int i = start; i < end; i++) {if (posArr[end] > posArr[i]) {less = i;} else {more = more == end ? i : more;}}head.left = posToBST(posArr, start, less);head.right = posToBST(posArr, more, end - 1);return head;}// for test -- print treepublic static void printTree(Node head) {System.out.println("Binary Tree:");printInOrder(head, 0, "H", 17);System.out.println();}public static void printInOrder(Node head, int height, String to, int len) {if (head == null) {return;}printInOrder(head.right, height + 1, "v", len);String val = to + head.value + to;int lenM = val.length();int lenL = (len - lenM) / 2;int lenR = len - lenM - lenL;val = getSpace(lenL) + val + getSpace(lenR);System.out.println(getSpace(height * len) + val);printInOrder(head.left, height + 1, "^", len);}public static String getSpace(int num) {String space = " ";StringBuffer buf = new StringBuffer("");for (int i = 0; i < num; i++) {buf.append(space);}return buf.toString();}public static void main(String[] args) {int[] arr = { 2, 1, 3, 6, 5, 7, 4 };System.out.println(isPost(arr, 0, arr.length - 1));printTree(posArrayToBST(arr));}
}

leetcode 449. Serialize and Deserialize BST | 449. 序列化和反序列化二叉搜索树(BST后序遍历性质)相关推荐

  1. 【LeetCode】剑指 Offer 33. 二叉搜索树的后序遍历序列

    [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 文章目录 [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 package offer;public cl ...

  2. 【数据结构与算法】之深入解析“序列化和反序列化二叉搜索树”的求解思路与算法示例

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

  3. 序列化和反序列化二叉搜索树 Serialize and Deserialize BST

    2019独角兽企业重金招聘Python工程师标准>>> 问题: Serialization is the process of converting a data structure ...

  4. leetcode算法题--二叉搜索树的后序遍历序列

    原题链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/ bool verifyP ...

  5. LeetCode 98. 验证二叉搜索树(中序遍历)

    文章目录 1. 题目信息 2. 解题 2.1 递归中序 2.2 非递归中序 1. 题目信息 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于 ...

  6. 二叉搜索树的中序遍历为 递增序列_Go 刷 Leetcode 系列:恢复二叉搜索树

    二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2输出: [3,1,null,null,2] 3 ...

  7. LeetCode 99. 恢复二叉搜索树(中序遍历)

    1. 题目 二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 你能想出一个只使用常数空间的解决方案吗? 2. 解题 循环中序遍历(栈),记录不满足的节点,交换其val O( ...

  8. 判断给定序列是否为BST后序遍历序列

    输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.假设输入的数组的任意两个数字都互不相同. 目录 一.BST 1.1 定义 1.2 性质 二.思路 2.1 非递归版本 2.2 递归版本 ...

  9. Leetcode 106. 从中序与后序遍历序列构造二叉树 解题思路及C++实现

    解题思路: 思路和Leetcode 105题相同.区别在于,在这一题中,后序遍历的最后一个值为根节点. 然后仍然是找到根节点后,划分左右子树,递归构建. /*** Definition for a b ...

最新文章

  1. Luogu P6055 [RC-02] GCD(莫比乌斯反演,杜教筛)(这题乐死我了,真就图一乐呗)
  2. 孔兵 库卡机器人_名企零距离 专访库卡首席执行官 孔兵先生
  3. 对CAS机制的理解(二)
  4. Oracle 数据库利用sql语句杀掉用户session进程,“ORA-01940: 无法删除当前连接的用户“问题解决办法
  5. The import javax.servlet cannot be resolved
  6. go使用grpc实现异步_(python、go)基于ETCD的gRPC分布式服务器实现详解
  7. android如何监听按钮,Android – 两个onClick监听器和一个按钮
  8. 三维重建10:点云配准和点云匹配
  9. java criteria exist_Java Criteria.addExists方法代碼示例
  10. python methodtype_Python的实例定属性和方法或类绑定方法
  11. React Native App设置amp;Android版发布
  12. nacos 本地测试_Nacos入门
  13. 第七代微软小冰发布:全双工语言交互技术已经通过车载设备完成测试
  14. mysql中用来取余数的函数是_Excel中一个专门用来评分的函数TRIMMEAN
  15. Java中condition的用法_java5 Condition用法--实现线程间的通信
  16. windows安装mysql-8.0.12-winx64和Navicat客户端连接(亲测有效)
  17. K8S_Google工作笔记0008---通过二进制方式_搭建集群介绍
  18. java scjp 试题_JAVA认证历年真题:SCJP考试真题和解析[1]
  19. Power BI前置知识+ 一张报表制作的流程
  20. VIT实战总结:非常简单的VIT入门教程,一定不要错过

热门文章

  1. SDUT - 2604 Thrall’s Dream(tarjan+拓扑)
  2. HDU - 3987 Harry Potter and the Forbidden Forest(最小割最少边数)
  3. HDU - 5978 To begin or not to begin(简单博弈)
  4. 透过汇编另眼看世界之函数调用
  5. PyCairo 中的剪裁和屏蔽
  6. 高性能、低成本的高防 IP 产品能现实吗?
  7. 如何选择适合自己网站的防盗链
  8. Flink 状态管理:算子状态、键值分区状态、状态后端、有状态算子的扩缩容
  9. C++ 类和对象(一):类的概念、类的访问控制和封装、类对象模型、this指针
  10. 单元测试之带你搞懂Mockito使用