LeetCode 297. 二叉树的序列化与反序列化

蹲街弑〆低调 提交于 2020-05-09 16:06:36

我的LeetCode:https://leetcode-cn.com/u/ituring/

我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii

LeetCode 297. 二叉树的序列化与反序列化

题目

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

__示例: __

你可以将以下二叉树:

    1
   / \
  2   3
     / \
    4   5

序列化为 "[1,2,3,null,null,4,5]"

提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

示例提供的只是一个演示,实际序列化成的数据格式和反序列化的逻辑不用与示例一致,只要保证实现的两个方法可以让数据成功互转即可;

思路1-BFS/广度优先/树的层次遍历

序列化:按照树的层逐层序列化,null值序列化为"null",用","p拼接;
反序列化:用“,”分割获得数组,首个值为树的根节点,然后给树安排左右子节点,仍然是按照BFS的逻辑反向还原即可;

算法复杂度:

  • 时间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
  • 空间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

思路2-DFS/深度优先/树的先序遍历

序列化:直接按照先序遍历的顺序递归序列化树;
反序列化:反向递归还原树,注意左右子树的还原顺序;

算法复杂度:

  • 时间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
  • 空间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

算法源码示例

package leetcode;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Objects;

/**
 * @author ZhouJie
 * @date 2020年5月3日 下午11:42:01 
 * @Description: 297. 二叉树的序列化与反序列化
 *
 */
public class LeetCode_0297 {

}

//Definition for a binary tree node.
class TreeNode_0297 {
	int val;
	TreeNode_0297 left;
	TreeNode_0297 right;

	TreeNode_0297(int x) {
		val = x;
	}
}

/**
* @author ZhouJie
* @date 2020年5月3日 下午10:48:39 
* @Description: 1-层次遍历/BFS,使用LinkedList记录节点;
*
*/
class Codec_297_1 {

// Encodes a tree to a single string.
	public String serialize(TreeNode_0297 root) {
		if (root == null) {
			return "";
		}
		LinkedList<TreeNode_0297> queue = new LinkedList<TreeNode_0297>();
		StringBuilder sb = new StringBuilder("[");
		queue.offer(root);
		while (!queue.isEmpty()) {
			TreeNode_0297 node = queue.poll();
			if (node != null) {
				sb.append(node.val);
				queue.offer(node.left);
				queue.offer(node.right);
			} else {
				sb.append("null");
			}
			sb.append(",");
		}
		return sb.deleteCharAt(sb.length() - 1).append("]").toString();
	}

// Decodes your encoded data to tree.
	public TreeNode_0297 deserialize(String data) {
		if (data == null || data.isEmpty()) {
			return null;
		}
		String[] nodeArray = data.substring(1, data.length() - 1).split(",");
		int i = 0;
		TreeNode_0297 root = buildeNode(nodeArray[i++]);
		LinkedList<TreeNode_0297> queue = new LinkedList<TreeNode_0297>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			TreeNode_0297 node = queue.poll();
			node.left = buildeNode(nodeArray[i++]);
			node.right = buildeNode(nodeArray[i++]);
			if (node.left != null) {
				queue.offer(node.left);
			}
			if (node.right != null) {
				queue.offer(node.right);
			}
		}
		return root;
	}

	private TreeNode_0297 buildeNode(String s) {
		if (Objects.equals(s, "null")) {
			return null;
		} else {
			return new TreeNode_0297(Integer.valueOf(s));
		}
	}
}

/**
* @author ZhouJie
* @date 2020年5月3日 下午11:24:23 
* @Description: 2-DFS
*
*/
class Codec_297_2 {

// Encodes a tree to a single string.
	public String serialize(TreeNode_0297 root) {
		return serialize(root, new StringBuilder());
	}

	private String serialize(TreeNode_0297 root, StringBuilder sb) {
		if (root == null) {
			sb.append("null,");
		} else {
			sb.append(root.val).append(",");
			serialize(root.left, sb);
			serialize(root.right, sb);
		}
		return sb.toString();
	}

// Decodes your encoded data to tree.
	public TreeNode_0297 deserialize(String data) {
		return deserialize(new LinkedList<String>(Arrays.asList(data.split(","))));
	}

	private TreeNode_0297 deserialize(LinkedList<String> list) {
		String s = list.get(0);
		list.remove(0);
		if (Objects.equals(s, "null")) {
			return null;
		} else {
			TreeNode_0297 root = buildeNode(s);
			root.left = deserialize(list);
			root.right = deserialize(list);
			return root;
		}
	}

	private TreeNode_0297 buildeNode(String s) {
		if (Objects.equals(s, "null")) {
			return null;
		} else {
			return new TreeNode_0297(Integer.valueOf(s));
		}
	}
}
//Your Codec object will be instantiated and called as such:
//Codec codec = new Codec();
//codec.deserialize(codec.serialize(root));

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!