題目描述
序列化是將一個數據結構或者對象轉換爲連續的比特位的操作,進而可以將轉換後的數據存儲在一個文件或者內存中,同時也可以通過網絡傳輸到另一個計算機環境,採取相反方式重構得到原數據。
請設計一個算法來實現二叉樹的序列化與反序列化。這裏不限定你的序列 / 反序列化算法執行邏輯, 你只需要保證一個二叉樹可以被序列化爲一個字符串並且將這個字符串反序列化爲原始的樹結構。
示例:
你可以將以下二叉樹:
1
/ \
2 3
/ \
4 5a
序列化爲 “[1,2,3,null,null,4,5]”
說明: 不要使用類的成員 / 全局 / 靜態變量來存儲狀態,你的序列化和反序列化算法應該是無狀態的。
解法
採用先序遍歷,對二叉樹進行序列化。
每到達一個節點,將節點的值+逗號添加到StringBuilder中,遇到空節點則添加null。最後轉換爲字符串返回。
避免使用字符串拼接,性能太差。
例子中的樹序列化後的結果爲:“1,2,null,null,3,4,null,null,5,null,null,”
public String serialize(TreeNode root) {
StringBuilder res = serializeHelper(root, new StringBuilder());
return res.toString();
}
public StringBuilder serializeHelper(TreeNode root, StringBuilder sb) {
if (root == null) {
sb.append("null,");
} else {
sb.append(root.val);
sb.append(",");
serializeHelper(root.left, sb);
serializeHelper(root.right, sb);
}
return sb;
}
反序列化時,先將字符串根據逗號分隔爲字符串數組,進而轉化爲list,然後從左向右遍歷這個序列,根據序列的首位元素構造節點,每次處理完,刪除序列中的該元素:
- 如果當前的元素爲 None,則當前爲空樹
- 否則先構造這棵樹的左子樹,再構造它的右子樹。
public TreeNode deserialize(String data) {
String[] data_array = data.split(",");
List<String> data_list = new LinkedList<String>(Arrays.asList(data_array));
return deserializeHelper(data_list);
}
public TreeNode deserializeHelper(List<String> list) {
if (list.get(0).equals("null")) {
list.remove(0);
return null;
}
TreeNode root = new TreeNode(Integer.valueOf(list.get(0)));
list.remove(0);
root.left = deserializeHelper(list);
root.right = deserializeHelper(list);
return root;
}
整體提交結果:
執行用時:12 ms, 在所有 Java 提交中擊敗了86.23%的用戶
內存消耗:41.1 MB, 在所有 Java 提交中擊敗了28.57%的用戶