剑指 Offer 37. 序列化二叉树(剑指 Offer II 048. 序列化与反序列化二叉树 && 297. 二叉树的序列化与反序列化)
题目:
思路:
【1】该题目算是开放式的吧,并没有什么标准,也就是说,输入可以自己定,也可以常规的[1,2,3,null,null,4,5,null,null,null,null]或者[1,2,3,null,null,4,5],但是需要的是你自己能识别,然后能转成树,又能从树转回去即可。其实思想最接近的就是层次遍历了,因为层次遍历的顺序和题目一开始给的示例的顺序是最接近的也是最容易想到的,而后序遍历和前序遍历都是可以做的,但是会复杂点。
代码展示:
基于层次遍历的思想:
//时间22 ms击败26.33% //内存44.1 MB击败28.71% /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { // Encodes a tree to a single string. // 这里基于层次遍历再次将树转为字符串 // 如果是输入[1,2,3,null,null,4,5]的树 // 输出会是[1,2,3,null,null,4,5,null,null,null,null],这里的null都被补上了 public String serialize(TreeNode root) { if(root == null) return "[]"; StringBuilder res = new StringBuilder("["); Queue<TreeNode> queue = new LinkedList<TreeNode>() {{ add(root); }}; while(!queue.isEmpty()) { TreeNode node = queue.poll(); if(node != null) { res.append(node.val + ","); queue.add(node.left); queue.add(node.right); }else { res.append("null,"); } } res.deleteCharAt(res.length() - 1); res.append("]"); return res.toString(); } // Decodes your encoded data to tree. // 基于层次遍历的思路来做的,因为这种输出方式不就是层次遍历的输出? // 只不过如果数组后面是null的那部分取消了,中间的没有取消 // 输入的形式String data = "[1,2,3,null,null,4,5]"; public TreeNode deserialize(String data) { if(data.equals("[]")) return null; String[] vals = data.substring(1, data.length() - 1).split(","); TreeNode root = new TreeNode(Integer.parseInt(vals[0])); Queue<TreeNode> queue = new LinkedList<TreeNode>() {{ add(root); }}; int i = 1; //这里要判断不要进行数组越界 while(!queue.isEmpty() && i < vals.length) { TreeNode node = queue.poll(); if(!vals[i].equals("null")) { node.left = new TreeNode(Integer.parseInt(vals[i])); queue.add(node.left); } i++; if(!vals[i].equals("null")) { node.right = new TreeNode(Integer.parseInt(vals[i])); queue.add(node.right); } i++; } return root; } }
采用StringJoiner替换StringBuilder,将效率提升:
//时间19 ms击败53.51% //内存43.9 MB击败41.53% import java.util.StringJoiner; public class Codec { // Encodes a tree to a single string. public String serialize(TreeNode root) { StringJoiner res = new StringJoiner(",","[","]"); if(root == null) return res.toString(); Queue<TreeNode> queue = new LinkedList<TreeNode>() {{ add(root); }}; while(!queue.isEmpty()) { TreeNode node = queue.poll(); if(node != null) { res.add(node.val+""); queue.add(node.left); queue.add(node.right); }else { res.add("null"); } } return res.toString(); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { if(data.equals("[]")) return null; String[] vals = data.substring(1, data.length() - 1).split(","); TreeNode root = new TreeNode(Integer.parseInt(vals[0])); Queue<TreeNode> queue = new LinkedList<TreeNode>() {{ add(root); }}; int i = 1; //这里要判断不要进行数组越界 while(!queue.isEmpty() && i < vals.length) { TreeNode node = queue.poll(); if(!vals[i].equals("null")) { node.left = new TreeNode(Integer.parseInt(vals[i])); queue.add(node.left); } i++; if(!vals[i].equals("null")) { node.right = new TreeNode(Integer.parseInt(vals[i])); queue.add(node.right); } i++; } return root; } }