日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/2/28 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 449. Serialize and Deserialize BST | 449. 序列化和反序列化二叉搜索树(BST后序遍历性质) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目

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

題解

本題的難點(diǎn)在于 利用 BST 的性質(zhì)

幾個(gè)提示
  • 根據(jù)后序遍歷BST性質(zhì),頭結(jié)點(diǎn)是最后一個(gè)元素,且有一個(gè)分界,滿足比頭結(jié)點(diǎn)小的都在左邊,比頭結(jié)點(diǎn)大的都在右邊
  • 本題滿足條件(但是題目中沒說)沒有重復(fù)值
  • 要求你返回的樹的形狀不僅是 BST,而且要與輸入完全相同。同樣是 BST,注意以下兩樹的區(qū)別。它們中序序列相同,后序序列不同。
對比

一開始我想,這不就是序列化/反序列化一棵普通樹嗎?只不過給你的時(shí)候恰好是 BST。這和 297. Serialize and Deserialize Binary Tree 有什么不同?

再一想,不一樣。利用二叉樹的性質(zhì),可以將序列化結(jié)果簡化,也就是本題說的 The encoded string should be as compact as possible. 編碼的字符串應(yīng)盡可能緊湊

參考左神算法書 P107 “二叉樹的序列化和反序列化”,他在序列化一棵普通樹的時(shí)候,利用了先序遍歷的方式,用 # 記錄空節(jié)點(diǎn)。而本題是 BST,其本身性質(zhì)決定了不需要通過 # 記錄空節(jié)點(diǎn),也能進(jìn)行 唯一結(jié)果的 序列化與反序列化。

附從錯(cuò)誤思路到正確思路的草稿:

/*** 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);}// 根據(jù)后序遍歷BST性質(zhì),頭結(jié)點(diǎn)是最后一個(gè)元素,且有一個(gè)分界,滿足比頭結(jié)點(diǎn)小的都在左邊,比頭結(jié)點(diǎn)大的都在右邊public TreeNode buildBST(int[] arr, int L, int R) {if (L > R) return null;TreeNode node = new TreeNode(arr[R]);// 找左右子樹的分界點(diǎn)int M = L;while (arr[M] < arr[R]) {M++;}// M指向分界點(diǎn)右邊第一個(gè)元素,本題缺隱含條件:沒有重復(fù)值!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;

可參考:左程云《程序員代碼面試指南》根據(jù)后序數(shù)組重建搜索二叉樹


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));} }

總結(jié)

以上是生活随笔為你收集整理的leetcode 449. Serialize and Deserialize BST | 449. 序列化和反序列化二叉搜索树(BST后序遍历性质)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。