题解 | #序列化二叉树#
序列化二叉树
https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84
层次遍历的序列化和反系列化,其中我添加了parseTreeNode方法,用于将字符串解析为二叉树节点
#刷题#
import java.util.*; /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { // 层次遍历的序列化 String Serialize(TreeNode root) { if (root == null) // 空树返回空字符串 return ""; // 空节点用'#'表示, 节点之间用','分割 StringBuilder sb = new StringBuilder(); // 允许空节点入队 Queue<TreeNode> q = new LinkedList<>(); q.offer(root); while (!q.isEmpty()) { // 当前层的节点数 int n = q.size(); // 判断当前层是否为最后一层的下一层(全为空节点), 是则结束,否则继续遍历 int numOfNull = 0; // 空节点数 for (TreeNode node : q) { if (node == null) numOfNull++; } if (numOfNull == n) // 说明当前层全为空节点,结束 break; // 遍历一层的节点 for (int i = 0; i < n; i++) { root = q.poll(); if (root == null) { sb.append("#,"); q.offer(null); q.offer(null); } else { sb.append(Integer.toString(root.val) + ","); q.offer(root.left); q.offer(root.right); } } } // 比如:示例例结果为:"1,2,3,#,#,6,7," // 反序列化时:split(",")的结果数组里最后一个元素为7,即最后的逗号不影响分割结果,会自动将最后的空字符删除,具体可见split的源码 return sb.toString(); } TreeNode Deserialize(String str) { if ("".equals(str)) // 空树返回null return null; TreeNode head = null; // 反序列化后的树根 String[] vals = str.split(","); // 需要一个存放树节点的列表,用来找到当前遍历节点的父节点,才能串联成树 List<TreeNode> nodes = new ArrayList<>(); // 初始化树根: head = parseTreeNode(vals[0]); nodes.add(head); // 从第2个节点开始遍历 for (int i = 1; i < vals.length; i++) { TreeNode node = parseTreeNode(vals[i]); // 添加到nodes中:(空节点也要添加到nodes中,才能保持下标的正确性) nodes.add(node); if (node == null) { // 如果为空节点,则不需要与父节点串联了 continue; } // 串联父子节点: // 节点i的父节点下标为:(i-1)/2 TreeNode parentNode = nodes.get((i-1)/2); // 确定当前节点为父节点的 左 还是 右 孩子节点: // 下标i为奇数则为左孩子,为偶数则为右孩子 if (i % 2 == 0) { parentNode.right = node; } else { parentNode.left = node; } } return head; } // 将字符串解析为二叉树节点 public TreeNode parseTreeNode(String str) { TreeNode node = null; if ("#".equals(str)) { return null; } else { int val = Integer.parseInt(str); node = new TreeNode(val); } return node; } }
#刷题#