leetcode-pp / 91alg-6-daily-check

91 算法第六期打卡仓库
28 stars 0 forks source link

【Day 17 】2021-12-28 - 297. 二叉树的序列化与反序列化 #24

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

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

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

前置知识

暂无

题目描述

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

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

示例: 

你可以将以下二叉树:

    1
   / \
  2   3
     / \
    4   5

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

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

思路: 解法1:DFS 采用前序遍历节点构造序列串。 =》关键在于判断root是否为nil,是的话返回"X"。此外返回值是拼接字符串,用“,”分割便于合成字符串数组。 对于反序列化。 首先通过strings.Split将字符串拆成字符串数组list,便于处理。 此外内部定义一个构造树函数,通过前序遍历list,依次构造树。 如果值为X,则返回nil。然后前序遍历的方式构造根结点。 细节:为什么要用指针?因为局部变量操作【修改】全局变量时,需要在内存中进行。

type Codec struct {
    Tree *TreeNode
}

func Constructor() Codec {
    return Codec{}
}

// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
    if root == nil{
        return "X"
    }
    return strconv.Itoa(root.Val) + "," + this.serialize(root.Left) + "," + this.serialize(root.Right)
}

// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {    
    list := strings.Split(data,",")
    var buildTree func(list *[]string) *TreeNode
    buildTree = func(list *[]string) *TreeNode{
        rootVal := (*list)[0]
        *list = (*list)[1:]
        if rootVal == "X"{
            return nil
        }
        v,_ := strconv.Atoi(rootVal)
        root := &TreeNode{Val:v}
        root.Left = buildTree(list)
        root.Right = buildTree(list)
        return root
    }
    return buildTree(&list)

}

时间复杂度O(n) 空间复杂度O(n)

思路2:BFS 对于序列化,维护一个队列对root进行BFS搜索,与前面BFS模板区别在于这里遇到nil节点,也插入到队列中。 PS:用string数组来装Val值,最后利用strings.Join(out, ",") 将string数组 拼接成一个string 对于反序列化,先判断data是否只有一个X,不是则继续。 用strings.Split将string拆除string数组便于处理。 由于是二叉树,所以index每次移动两次。 先获取一个根节点,将data值转换成val,for循环遍历list 取出节点后,index对于该节点的左节点,index+1对于该节点的右节点。 判断是否为“X”,不是则将值赋值给节点,并接入node对应的子树。随后将该节点入队列。 最后返回root

type Codec struct {
    Tree *TreeNode
}

func Constructor() Codec {
    return Codec{}
}

// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
    if root == nil{
        return "X"
    }
    out := []string{}
    queue := []*TreeNode{root}
    for len(queue) > 0{
        length := len(queue)
        for i:=0;i<length;i++{
            node := queue[0]
            queue = queue[1:]
            if node != nil{
                out = append(out,strconv.Itoa(node.Val))
                queue = append(queue,node.Left)
                queue = append(queue,node.Right)
            }else{
                out = append(out,"X")
            }

        }
    }
    return strings.Join(out,",")
}

// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {    
    if data == "X"{
        return nil
    }
    list := strings.Split(data, ",")
    val,_ := strconv.Atoi(list[0])
    root := &TreeNode{Val:val}
    queue := []*TreeNode{root}
    index := 1
    for index < len(list){
        node := queue[0]
        queue = queue[1:]
        leftVal := list[index]
        RightVal := list[index+1]
        if leftVal != "X"{
            v,_ := strconv.Atoi(leftVal)
            leftNode := &TreeNode{Val:v}
            node.Left = leftNode
            queue = append(queue,leftNode)
        }
        if RightVal != "X"{
            v,_ := strconv.Atoi(RightVal)
            rightNode := &TreeNode{Val:v}
            node.Right = rightNode
            queue = append(queue,rightNode)
        }
        index += 2
    }
    return root
}

时间复杂度O(n) 空间复杂度O(n)

CoreJa commented 2 years ago

思路

代码

# 朴素BFS思路:第一次写的有些青涩,基本思路就是队列作为辅助空间,层序遍历(并且把null带上)。反序列化类似操作。
class Codec1:
    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        ans = []
        if not root:
            return str(ans)

        q = deque([root])
        while q:
            for _ in range(len(q)):
                node = q.popleft()
                if node:
                    q.append(node.left)
                    q.append(node.right)
                    ans.append(node.val)
                else:
                    ans.append(None)

        return str(ans)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        data = data.strip('[]').replace(' ', '')
        if not data:
            return None
        data = [int(d) if d != "None" else None for d in data.split(',')]
        root = TreeNode(data[0])
        q = deque([root])
        i = 1
        while i < len(data):
            if q:
                node = q.popleft()
            else:
                break
            if data[i] != None:
                node.left = TreeNode(data[i])
                q.append(node.left)
            i += 1

            if i < len(data) and data[i] != None:
                node.right = TreeNode(data[i])
                q.append(node.right)
            i += 1
        return root

# BFS:和上述方法类似,略微改进调整,反序列化前删掉了多余的null,比前者思路更清晰
class Codec2:

    def serialize(self, root):
        q = deque([root])
        ans = ''
        while q:
            node = q.popleft()
            if node:
                ans += str(node.val) + ','
                q.append(node.left)
                q.append(node.right)
            else:
                ans += 'null,'
        return ans[:-1]

    def deserialize(self, data):
        data = data.split(',')
        i = len(data) - 1
        while i >= 0 and data[i] == 'null':
            i -= 1
        data = data[:i + 1]

        n = len(data)
        if not data:
            return None

        root = TreeNode(data[0])
        q = deque([root])
        i = 1
        while q and i < n:
            node = q.popleft()
            if i < n and data[i] != 'null':
                node.left = TreeNode(data[i])
                q.append(node.left)
            i += 1
            if i < n and data[i] != 'null':
                node.right = TreeNode(data[i])
                q.append(node.right)
            i += 1
        return root

# DFS:递归,YYDS。不得不说这个思路太妙了,其实复杂度和BFS一样,只是递归代码量少很多,运行起来无比玄妙,具体来说就是:
# - 序列化:先序遍历,用`,`隔开
# - 反序列化:`data=data.split(',')`,然后整个`nonlocal`变量`i`,递归过程中`data[i]`就是根节点(先序遍历),`i+=1`,然后左子树右子树分别递归调用即可。
class Codec:

    def serialize(self, root):
        if not root:
            return 'null'
        return str(root.val) + ',' + self.serialize(root.left) + ',' + self.serialize(root.right)

    def deserialize(self, data):
        i = 0
        data = data.split(',')

        def dfs():
            nonlocal i
            if data[i] == 'null':
                i += 1
                return None
            root = TreeNode(data[i])
            i += 1
            root.left = dfs()
            root.right = dfs()
            return root

        return dfs()
yetfan commented 2 years ago

思路 bfs python竟然输出的是 ‘[’ str... ‘]’ ... list里是字符串就算了,你括号都是字符串就离谱 搞死我了

serialize: bfs遍历 是节点就往队列里插 节点为空 结果插入“None”,否则插入值 str(node.val) 最后整理一下,转换输出字符串 '【' + list_elements +'】'

deserialize: 按照data新建节点, 不为空的节点 按照左右顺序插在当前节点上, 生成的节点不停的进入检测队列

代码

class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ""
        self.open = [root]
        self.res = []
        self.children = []

        while self.open:
            node = self.open.pop(0)
            if node:
                self.res.append(str(node.val))
                self.open.append(node.left)
                self.open.append(node.right)
            else:
                self.res.append('None')
        # return self.res
        return '[' + ','.join(self.res) + ']'

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        if not data:
            return []
        dataList = data[1:-1].split(',')
        root = TreeNode(int(dataList[0]))
        self.open = [root]
        i = 1
        while self.open:
            node = self.open.pop(0)
            if dataList[i] != 'None':
                node.left = TreeNode(int(dataList[i]))
                self.open.append(node.left)
            i += 1
            if dataList[i] != 'None':
                node.right = TreeNode(int(dataList[i]))
                self.open.append(node.right)
            i += 1
        return root

复杂度 时间 O(n) 空间 O(n)

charlestang commented 2 years ago

思路

序列化:前序遍历的结果,存储在列表里,然后用逗号连接。注意要把空节点也序列化出来,作为反序列化时候的边界。

反序列化:按照前序遍历的顺序,逆向构建树。遇到 None,则说明遇到了边界(叶子节点),可以直接返回,否则需要构建左子树和右子树。

代码

class Codec:

    def serialize(self, root):
        ans = []
        def preorder(root):
            if not root: return ans.append('None')
            ans.append(str(root.val))
            preorder(root.left)
            preorder(root.right)
        preorder(root)
        return ','.join(ans)

    def deserialize(self, data):
        nodes = data.split(',')
        i = 0
        def buildpre():
            nonlocal i
            if nodes[i] == 'None': 
                i += 1
                return None
            root = TreeNode(int(nodes[i]))
            i += 1
            root.left = buildpre()
            root.right = buildpre()
            return root
        return buildpre()

时间复杂度 O(n)

空间复杂度 O(n)

wangzehan123 commented 2 years ago

代码

Java Code:


/**
 * 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.
    public String serialize(TreeNode root) {
        if(root == null){
            return "";
        }
        StringBuilder res = new StringBuilder();
        res.append("[");
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            if(node != null){
                res.append(node.val);
                queue.offer(node.left);
                queue.offer(node.right);
            }else{
                res.append("null");
            }
            res.append(",");
        }
        res.append("]");
        return res.toString();
    }

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

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));
q815101630 commented 2 years ago

DFS 我们可以用一个preorder bfs 把空节点也记录一下,然后在反序列化中能够用相同操作preorder 如法炮制

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        def recur(root, ans):
            if not root:
                ans.append("N")
                return
            ans.append(str(root.val))
            recur(root.left, ans)
            recur(root.right, ans)
        ans =[]
        recur(root, ans)
        return "/".join(ans)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        if not data:
            return None
        data = data.split("/")
        data = data[::-1]
        def recur(data):
            popped = data.pop()
            if popped == "N":
                return None
            node = TreeNode(popped)
            node.left = recur(data)
            node.right = recur(data)
            return node
        return recur(data)

# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

时间 O(n) 空间 O(n)

zwmanman commented 2 years ago

思路

  1. BFS each node, if it is valid node add its value otherwise add '#'
  2. deserise keep an isLeft flag

代码

(此处撰写代码)

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        queue = [root]
        res = []

        while queue:
            curr = queue.pop(0)
            res.append(str(curr.val) if curr else '#')
            if curr:
                queue.append(curr.left)
                queue.append(curr.right)

        return ' '.join(res)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        bfs = [ch for ch in data.split()]
        if bfs[0] == '#':
            return None
        #{3,9,20,#,#,15,7}
        root = TreeNode(int(bfs.pop(0)))
        queue = [root]
        isLeft = True
        while queue:
            child = bfs.pop(0)
            if child != '#':
                node = TreeNode(int(child))
                queue.append(node)
                if isLeft:
                    queue[0].left = node
                else:
                    queue[0].right = node

            if not isLeft:
                queue.pop(0)
            isLeft = not isLeft

        return root

复杂度分析

ZacheryCao commented 2 years ago

Idea

BFS. Use "#" to represent None node and "$" to separate each node in the string. In the deserialization, split the string by "$" and convert it to a deque Data. Use an extra deque S to record current layer's node excluding None node. For each node in S, its left and right child's value should be the first two elements in the Data. After pop the first two elements in Data, if they are "#", then the node is None. Else, build the new node with the value represented by the element and attach the new node to the end of the S.

Code

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        stack = collections.deque()
        stack.append(root)
        ans = ""
        while stack:
            cur = stack.popleft()
            if cur == None:
                ans = ans + "$#" if ans else "#"
            else:
                ans = ans + "$"+str(cur.val) if ans else str(cur.val)
                stack.append(cur.left)
                stack.append(cur.right)
        return ans

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        data = collections.deque(data.split("$"))
        head = None
        stack = collections.deque()
        while data:
            if not head:
                cur = data.popleft()
                if cur == "#":
                    return None
                head = TreeNode(int(cur))
                stack.append(head)
                continue
            else:
                l = len(stack)
                for _ in range(l):
                    cur = stack.popleft()
                    n1 = data.popleft()
                    n2 = data.popleft()
                    cur.left = None if n1 == "#" else TreeNode(int(n1))
                    cur.right = None if n2 == "#" else TreeNode(int(n2))
                    if cur.left:
                        stack.append(cur.left)
                    if cur.right:
                        stack.append(cur.right)
        return head

Complexity:

Time: O(N) Space: O(N)

zjsuper commented 2 years ago

bfs

class Codec:

def serialize(self, root):
    """Encodes a tree to a single string.
    :type root: TreeNode
    :rtype: str
    """
    if root is None:
        return ''
    queue = deque()
    queue.append(root)
    nodes = []
    while len(queue) > 0:
        cur_node = queue.popleft()
        if cur_node is None:
            nodes.append('n')
            continue
        else:
            nodes.append(str(cur_node.val))
        queue.append(cur_node.left)
        queue.append(cur_node.right)
    return ','.join(nodes)

def deserialize(self, data):
    """Decodes your encoded data to tree.
    :type data: str
    :rtype: TreeNode
    """
    if len(data) == 0:
        return None
    nodes = data.split(',')
    root_node = TreeNode(int(nodes[0]))
    queue = deque()
    queue.append(root_node)
    cur_pos = 1
    while len(queue) > 0:
        cur = queue.popleft()
        if nodes[cur_pos] != 'n':
            cur.left = TreeNode(int(nodes[cur_pos]))
            queue.append(cur.left)
        cur_pos += 1
        if nodes[cur_pos] != 'n':
            cur.right = TreeNode(int(nodes[cur_pos]))
            queue.append(cur.right)
        cur_pos += 1
    return root_node
hwpanda commented 2 years ago
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function (root, emptyMarker = '#', seperator = ',') {
    if (!root) return '';
    let str = '';
    preorder(root);
    // 删除最后的分隔符
    return str.slice(0, -1);

    // *******************************
    function preorder(root) {
        if (!root) {
            str += emptyMarker + seperator;
            return;
        }
        str += root.val + seperator;
        preorder(root.left);
        preorder(root.right);
    }
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function (data, emptyMarker = '#', seperator = ',') {
    if (!data) return null;
    const nodes = data.split(seperator);
    let i = 0;
    return preorder();

    // *********************************
    function preorder() {
        if (i >= nodes.length || nodes[i] === emptyMarker) return null;

        const node = new TreeNode(nodes[i]);
        i++;
        node.left = preorder();
        i++;
        node.right = preorder();

        return node;
    }
};
zwx0641 commented 2 years ago

public class Codec {

String empty = "#";
String comma = ",";
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
    StringBuilder sb = new StringBuilder();
    se(root, sb);
    return sb.toString();
}

void se(TreeNode root, StringBuilder sb) {
    if (root == null) {
        sb.append(empty).append(comma);
        return;
    }

    se(root.left, sb);
    se(root.right, sb);
    sb.append(root.val).append(comma);
}

// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
    LinkedList<String> nodes = new LinkedList<>();
    for (String s : data.split(comma)) {
        nodes.addLast(s);
    }
    return de(nodes);
}

TreeNode de(LinkedList<String> nodes) {
    if (nodes.isEmpty()) return null;

    String first = nodes.removeLast();
    if (first.equals(empty)) return null;
    TreeNode root = new TreeNode(Integer.parseInt(first));
    root.right = de(nodes);
    root.left = de(nodes);
    return root;
}

}

laofuWF commented 2 years ago
# pre-order travsersal
# store values separated by comma when serializing
# build tree by traversing store values
# time/space: O(N)
class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return 'null'
        left = self.serialize(root.left)
        right = self.serialize(root.right)

        return str(root.val) + ',' + left + ',' + right

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        return self.build(data.split(','))

    def build(self, values):
        curr_value = values.pop(0)
        if curr_value == 'null':
            return None

        node = TreeNode(curr_value)
        # values list will be updated after every recursion
        node.left = self.build(values)
        node.right = self.build(values)

        return node
RocJeMaintiendrai commented 2 years ago

public class Codec {

// Encodes a tree to a single string.
public String serialize(TreeNode root) {
    if(root == null) return "";
    StringBuilder res = new StringBuilder();
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while(!queue.isEmpty()) {
        TreeNode cur = queue.poll();
        if(cur == null) {
            res.append("null,");
            continue;
        }
        res.append(cur.val + ",");
        queue.offer(cur.left);
        queue.offer(cur.right);
    }
    return res.toString();
}

// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
    if(data == "") return null;
    String[] strs = data.split(",");
    TreeNode root = new TreeNode(Integer.parseInt(strs[0]));
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    for(int i = 1; i < strs.length; i++) {
        TreeNode cur = queue.poll();
        if(!strs[i].equals("null")) {
            cur.left = new TreeNode(Integer.parseInt(strs[i]));
            queue.offer(cur.left);
        }
        i++;
        if(!strs[i].equals("null")) {
            cur.right = new TreeNode(Integer.parseInt(strs[i]));
            queue.offer(cur.right);
        }
    }
    return root;
}

}

zhangzz2015 commented 2 years ago

关键点

代码

C++ Code:


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string ret; 
        dfsToString(root, ret);
        return ret; 
    }

    void dfsToString(TreeNode* root, string& s)
    {
        if(root==NULL)
        {
            s.push_back('#');
            s.push_back(',');
            return; 
        }
        s+= to_string(root->val); 
        s.push_back(','); 
        dfsToString(root->left, s); 
        dfsToString(root->right, s);
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {

        int left =0; 
        return dfsToTree(data, left); 
    }

    TreeNode* dfsToTree(string& s, int& left)
    {
        if(left >= s.size())
            return NULL; 
        if(s[left] == '#')
        {
            left++;
            left++; 
            return NULL; 
        }
        int num =0;
        bool pos=true; 
        if(s[left]=='-')
        {
            pos=false; 
            left++; 
        }
        while(s[left]!=',')
        {
            num = num*10 + (s[left]-'0'); 
            left++;
        }
        if(pos==false)
            num = -num; 
        left++;        
        TreeNode* current = new TreeNode(num); 
        current->left = dfsToTree(s, left); 
        current->right = dfsToTree(s, left); 
        return current; 
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
Toms-BigData commented 2 years ago

【Day 17】297. 二叉树的序列化与反序列化

思路

将叶子节点的left和right也当做节点记录其中,这样整棵树就没有叶子节点,可以通过前序遍历整颗树,生成string。反序列化时候可以将其转换为字符数组,再次通过前序遍历,生成整颗树。

golang代码

type Codec struct {

}

func Constructor() Codec {
    return Codec{}
}

// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
    sb := strings.Builder{}
    var dfs func(*TreeNode)
    dfs = func(node *TreeNode){
        if node == nil{
            sb.WriteString("null,")
            return
        }
        sb.WriteString(strconv.Itoa(node.Val))
        sb.WriteByte(',')
        dfs(node.Left)
        dfs(node.Right)
    }
    dfs(root)
    return sb.String()
}

// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {    
    sp:=strings.Split(data, ",")
    var build func() *TreeNode
    build = func() *TreeNode {
        if sp[0] == "null"{
            sp = sp[1:]
            return nil
        }
        val,_ := strconv.Atoi(sp[0])
        sp = sp[1:]
        return &TreeNode{val, build(), build()}
    }
    return build()
}

复杂度

时间:O(n) 空间:O(n)

CodingProgrammer commented 2 years ago

思路

前序遍历

代码

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if (root == null)
            return "#!";
        StringBuilder sb = new StringBuilder();
        encode(root, sb);
        return sb.toString();
    }

    private void encode(TreeNode node, StringBuilder sb) {
        if (node == null) {
            sb.append("#!");
            return;
        }
        sb.append(node.val).append("!");
        encode(node.left, sb);
        encode(node.right, sb);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        // 按"!"切割字符串
        String[] values = data.split("!");
        Queue<String> dataQueue = new LinkedList<>(Arrays.asList(values));
        return decode(dataQueue);
    }

    private TreeNode decode(Queue<String> dataQueue) {
        if (dataQueue.isEmpty())
            return null;
        String val = dataQueue.poll();
        if (val.equals("#")) {
            return null;
        }
        TreeNode root = new TreeNode(Integer.parseInt(val));
        root.left = decode(dataQueue);
        root.right = decode(dataQueue);
        return root;
    }
}

复杂度

hdyhdy commented 2 years ago

思路: 序列化采用BFS,弹出的节点如果是null就将X推入答案切片,反之则将相应数值推入答案切片,同时将其左右子节点入列,直到所有内容都遍历了才算结束。 反序列化则同样采用BFS,此时不同的是维护一个指针,一次移动两步。当节点出列的时候, cursor 指向它的左子节点值,cursor+1 指向它的右子节点值。如果子节点值是数值,则创建节点,并认出列的父亲,同时自己也是父亲,入列。如果子节点值为 'X',什么都不用做,因为出列的父亲的 left 和 right 本来就是 null。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

type Codec struct {

}

func Constructor() (_ Codec) {
    return 
}

// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
    q :=[]*TreeNode {root}
    res := []string{}
    for len(q) != 0 {
        node := q[0]
        q = q[1:]
        if node != nil {
            res = append(res, strconv.Itoa(node.Val))
            q = append(q, node.Left)
            q = append(q, node.Right)
        }else {
            res = append(res,"X")
        }
    }
    return strings.Join(res, ",")
}

// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {    
    if data == "X" {
        return nil
    }
    list := strings.Split(data, ",")
    Val, _ := strconv.Atoi(list[0])
    root := &TreeNode{Val: Val}
    q := []*TreeNode{root}
    cursor := 1

    for cursor < len(list) {
        node := q[0]
        q = q[1:]
        leftVal := list[cursor]
        rightVal := list[cursor+1]
        if leftVal != "X" {
            v, _ := strconv.Atoi(leftVal)
            leftNode := &TreeNode{Val: v}
            node.Left = leftNode
            q = append(q, leftNode)
        }
        if rightVal != "X" {
            v, _ := strconv.Atoi(rightVal)
            rightNode := &TreeNode{Val: v}
            node.Right = rightNode
            q = append(q, rightNode)
        }
        cursor += 2
    }
    return root

}

/**
 * Your Codec object will be instantiated and called as such:
 * ser := Constructor();
 * deser := Constructor();
 * data := ser.serialize(root);
 * ans := deser.deserialize(data);
 */

复杂度: 时间为n,空间为n

Victoria011 commented 2 years ago

思路

Recursive preorder 的思路(dfs 比 bfs 更合适 考虑到后续 deserialize情况)。反序列化的时候通过 '#' 判断是否到达leaf。

代码

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        def doit(node):
            if node:
                vals.append(str(node.val))
                doit(node.left)
                doit(node.right)
            else:
                vals.append('#')
        vals = []
        doit(root)
        return ' '.join(vals)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        def doit():
            val = next(vals)
            if val == '#':
                return None
            node = TreeNode(int(val))
            node.left = doit()
            node.right = doit()
            return node
        vals = iter(data.split())
        return doit()

复杂度分析

Time Complexity: O(N)

Space Complexity: O(N)

EggEggLiu commented 2 years ago

代码

var serialize = function(root) {
    return rserialize(root, '');
};

var deserialize = function(data) {
    const dataArray = data.split(",");
    return rdeserialize(dataArray);
};

const rserialize = (root, str) => {
    if (root === null) {
        str += "None,";
    } else {
        str += root.val + '' + ",";
        str = rserialize(root.left, str);
        str = rserialize(root.right, str);
    }
    return str;
}

const rdeserialize = (dataList) => {
    if (dataList[0] === "None") {
        dataList.shift();
        return null;
    }

    const root = new TreeNode(parseInt(dataList[0]));
    dataList.shift();
    root.left = rdeserialize(dataList);
    root.right = rdeserialize(dataList);

    return root;
}
Joyce94 commented 2 years ago
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
    public String serialize(TreeNode root) {
        if (root == null) {
            return "";
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        List<Integer> res = new LinkedList<Integer>();
        queue.offer(root);
        //BFS
        while (!queue.isEmpty()) {
            TreeNode curNode = queue.poll();
            if (curNode != null) {
                res.add(curNode.val);
                queue.offer(curNode.left);
                queue.offer(curNode.right);
            } else {
                res.add(null);
            }
        } 
        return res.toString();
    }

    public TreeNode deserialize(String data) {
        if (data.length() == 0) {
            return null;
        }
        //将字符串还原为数组
        String[] preStr = data.substring(1, data.length() - 1).split(",");
        Integer[] bfsOrder = new Integer[preStr.length];
        for (int i = 0; i < preStr.length; i++) {
            if (preStr[i].trim().equals("null")) {
                bfsOrder[i] = null;
            } else {
                bfsOrder[i] = Integer.parseInt(preStr[i].trim());
            }
        }

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        TreeNode root = new TreeNode(bfsOrder[0]);
        int cur = 1;//通过 cur 指针依次给节点赋值
        queue.offer(root);
        while (!queue.isEmpty()) { 
            TreeNode curNode = queue.poll();
            if (bfsOrder[cur] != null) {
                curNode.left = new TreeNode(bfsOrder[cur]);
                queue.add(curNode.left);
            }
            cur++; 
            if (bfsOrder[cur] != null) {
                curNode.right = new TreeNode(bfsOrder[cur]);
                queue.add(curNode.right);
            }
            cur++;
        }
        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
ginnydyy commented 2 years ago

Problem

https://leetcode.com/problems/serialize-and-deserialize-binary-tree/

Note

Solution

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
    StringBuilder sb;

    private void serializeHelper(TreeNode root){
        if(root == null){
            sb.append("null,");
            return;
        }

        sb.append(root.val + ",");
        serializeHelper(root.left);
        serializeHelper(root.right);
    }

    private TreeNode desrializeHelper(List<Character> list){
        if("null")
    }

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root == null){
            return null;
        }
        sb = new StringBuilder();
        serializeHelper(root);
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data == null || data.isEmpty()){
            return null;
        }

        char[] chars = data.split(",");
        List<Character> list = new ArrayList<>();
        for(char c: chars){
            list.add(c);
        }

        TreeNode root = desrializeHelper(list);
        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

Complexity

SenDSproject commented 2 years ago

本题BFS, DFS都可以。这里贴一个DFS 的答案。用的还是分治的思想。



class Codec:

    def serialize(self, root):
        if not root:
            return 'None'
        return str(root.val) + ',' + str(self.serialize(root.left)) + ',' + str(self.serialize(root.right))

    def deserialize(self, data):
        def dfs(dataList):
            val = dataList.pop(0)
            if val == 'None':
                return None
            root = TreeNode(int(val))
            root.left = dfs(dataList)
            root.right = dfs(dataList)
            return root
        dataList = data.split(',')
        return dfs(dataList)

时间复杂度O(N)
空间复杂度O(N)
xuhzyy commented 2 years ago

思路

前序遍历和层序遍历

代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        # if not root:
        #     return 'None'

        # return str(root.val) + ',' + str(self.serialize(root.left)) + ',' + str(self.serialize(root.right))

        queue = collections.deque()
        queue.append(root)
        res = []
        while(queue):
            node = queue.popleft()
            if node:
                res.append(str(node.val))
                queue.append(node.left)
                queue.append(node.right)
            else:
                res.append('None')
        return '[' + ','.join(res) + ']'

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        # def dfs(dataList):
        #     val = dataList.pop(0)
        #     if val == 'None':
        #         return None

        #     root = TreeNode(int(val))
        #     root.left = dfs(dataList)
        #     root.right = dfs(dataList)
        #     return root

        # dataList = data.split(',')
        # return dfs(dataList)
        dataList = data[1:-1].split(',')
        if not data or dataList[0] == 'None':
            return None

        queue = collections.deque()
        root = TreeNode(int(dataList[0]))
        queue.append(root)
        i = 1
        while(queue):
            node = queue.popleft()
            if dataList[i] != 'None':
                node.left = TreeNode(int(dataList[i]))
                queue.append(node.left)
            i += 1

            if dataList[i] != 'None':
                node.right = TreeNode(int(dataList[i]))
                queue.append(node.right)
            i += 1
        return root

# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

复杂度分析

HondryTravis commented 2 years ago

思路

前序和层序遍历

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function (root) {
    const queue = [root];
    let res = [];
    while (queue.length) {
        const node = queue.shift()
        if (node) {
            res.push(node.val);
            queue.push(node.left);
            queue.push(node.right);
        } else {
            res.push('#')
        }
    }
    return res.join(',')
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function (data) {
    if (data == '#') return null;

    const list = data.split(',')

    const root = new TreeNode(list[0])
    const queue = [root]     
    let cursor = 1           

    while (cursor < list.length) {
        const node = queue.shift()

        const leftVal = list[cursor]
        const rightVal = list[cursor + 1]

        if (leftVal != '#') {            
            const leftNode = new TreeNode(leftVal)
            node.left = leftNode                
            queue.push(leftNode)                 
        }
        if (rightVal != '#') {
            const rightNode = new TreeNode(rightVal);
            node.right = rightNode
            queue.push(rightNode)
        }
        cursor += 2
    }
    return root
};

/**
 * Your functions will be called as such:
 * deserialize(serialize(root));
 */

复杂度分析

时间复杂度 O(n)

空间复杂度 O(n)

gentleman-goodman commented 2 years ago

Day_16_513_找树左下角的值.md

思路


参考别人的题解,dfs,bfs
    * 思路一:BFS
    * 序列化
   * 用BFS遍历树,与一般遍历的不同点是不管node的左右子节点是否存在,统统加到队列中
  * 在节点出队时,如果节点不存在,在返回值res中加入一个”null“;如果节点存在,则加入节点值的字符串形式
 * 反序列化
>* 同样使用BFS方法,利用队列新建二叉树
* 首先要将data转换成列表,然后遍历,只要不为null将节点按顺序加入二叉树中;同时还要将节点入队
   * 队列为空时遍历完毕,返回根节点
   * 作者:edelweisskoko
   * 链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/297-er-cha-shu-de-xu-lie-hua-yu-fan-xu-l-647c/
> > ```

代码


    public class Codec {

        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            if (root == null) {
                return "";
            }
            StringBuilder res = new StringBuilder();
            res.append("[");
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()) {

                TreeNode node = queue.poll();//取出并删除
                if (node != null) {
                    res.append("" + node.val);
                    queue.offer(node.left);
                    queue.offer(node.right);
                } else {
                    res.append("null");
                }
                res.append(",");

            }
            res.append("]");
            return res.toString();
        }

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

            }
            return root;

        }
    }

复杂度分析 时间复杂度:O(n) 空间复杂度:O(n)

GaoMinghao commented 2 years ago

思路

DFS

代码

/**
 * 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.
    public String serialize(TreeNode root) {
        if(root == null) return "";
        String[] elements = DFS(root).split(",");
        String result = "";
        for(String s:elements) {
            if(!s.isEmpty()) {
                result += s + ",";
            }
        }
        return result;
    }

    public String DFS(TreeNode root) {
        String result = root.val + ",";
        if(root.left!=null) {
            result += DFS(root.left) + ",";
        } else {
            result += "null"+",";
        }
        if(root.right!=null) {
            result += DFS(root.right) + ",";
        } else {
            result += "null"+",";
        }
        return result;
    }

    public TreeNode deserialize(String data) {
        if(data.equals("")) return null;
        List<String> elements = new ArrayList<String>(Arrays.asList(data.split(",")));
        return ReDFS(elements);
    }

    public TreeNode ReDFS(List<String> elements){
        String value = elements.get(0);
        elements.remove(0);
        if(value.equals("null")) {
            return null;
        }
        TreeNode root = new TreeNode(Integer.parseInt(value));
        root.left = ReDFS(elements);
        root.right = ReDFS(elements);
        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

时间复杂度

每个节点都要遍历一次,O(n)

shamworld commented 2 years ago
/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function(root) {
    const deep = (root,s) => {
        if(!root){
            s += 'NaN,';
        } else {
            s += root.val + ',';
            s = deep(root.left,s);
            s = deep(root.right,s);
        }
        return s;
    }

    return deep(root,'');
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function(data) {
    let arr = data.split(',');
    const deep = (list) => {
        const s = list.shift();
        if(s == 'NaN') return null;
        let root = new TreeNode(parseInt(s));
        root.left = deep(list);
        root.right = deep(list);

        return root;
    }

    return deep(arr);
};
pangjiadai commented 2 years ago

Python3

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        if not root: return "None"
        left = self.serialize(root.left)
        right = self.serialize(root.right)
        return str(root.val) + "," + left + "," + right 

    def deserialize(self, data):
        data_list = data.split(",")

        def buildTree(data_list):
            val = data_list.pop(0)
            if val == "None":
                return None
            root = TreeNode(val)
            root.left = buildTree(data_list)
            root.right = buildTree(data_list)
            return root

        root = buildTree(data_list)
        return root
Yachen-Guo commented 2 years ago

思路:

使用前序遍历+层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
    static final String NULL = "#";
    static final String SPLIT = ",";
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root == null) return "";
        StringBuilder sb = new StringBuilder();
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()){
            for(int i = 0; i < q.size(); i++){
                TreeNode node = q.poll();
            if(node == null){
                sb.append(NULL);
                sb.append(SPLIT);
            } else{
                sb.append(node.val);
                sb.append(SPLIT);
            }
            if(node == null){
                continue;
            }
            q.add(node.left);
            q.add(node.right);
            }
        }
        return sb.toString().substring(0,sb.toString().length()-1);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data.equals("")) return null;

        String[] nodeList = data.split(SPLIT);

        TreeNode root = new TreeNode(Integer.parseInt(nodeList[0]));

        Deque<TreeNode> tmp = new ArrayDeque<TreeNode>();
        tmp.add(root);
        for(int i = 1; i < nodeList.length;){
            TreeNode node = tmp.poll();
            if(nodeList[i].equals(NULL)){
                node.left = null;
            } else{
                node.left = new TreeNode(Integer.parseInt(nodeList[i]));
                tmp.add(node.left);
            }

            if(nodeList[i+1].equals(NULL)){
                node.right = null;
            } else{
                node.right = new TreeNode(Integer.parseInt(nodeList[i+1]));
                tmp.add(node.right);
            }
            i = i + 2;
    }
    return root;
}
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));
tongxw commented 2 years ago

思路

后序dfs序列化,先序dfs反序列化

代码

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if (root == null) {
            return "X";
        } else {
            return String.valueOf(root.val) + "," + serialize(root.left) + "," + serialize(root.right);
        }
    }

    // Decodes your encoded data to tree.
    int pos = 0;
    public TreeNode deserialize(String data) {
        String[] nodes = data.split(",");
        return dfs(nodes);
    }

    private TreeNode dfs(String[] nodes) {
        if (pos == nodes.length) {
            return null;
        }
        if (nodes[pos].equals("X")) {
            return null;
        }

        TreeNode root = new TreeNode(Integer.parseInt(nodes[pos]));
        pos++;
        root.left = dfs(nodes);
        pos++;
        root.right = dfs(nodes);
        return root;
    }
}

SC: O(N) TC: O(logN)

wenjialu commented 2 years ago

thought

iter through every node (either bfs or dfs) and put it's value into a string. bfs: use queue. init by putting root in it. take it(put it into res), put its left node and right node into it. next time, take its left node(put its left node and right node,even when they are null)... next time, take its right node,, put its left node and right node into queue.

code

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
import collections
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """

        if not root:
            return ""
        queue = collections.deque([root])
        res = []
        while queue:
            node = queue.popleft()
            if node:
                res.append(str(node.val)) 
                queue.append(node.left)
                queue.append(node.right)
            else:
                res.append("null") 
        return ",".join(res)     # 问题就出在字符串的处理上了。。  我得把list转换成str才能用join方法。。 我这个res一开始要init成list。

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        # turn string to list. init first ele in list as root.
        # put the root into a queue. take it from queue, put the next to as it's left node and roght node and put them into the queue, so that next time they would yici be the root.
        if data == "":
            return []
        # print(data)    
        data_list = data.split(",") # 这里没问题,问题就出在序列化方法字符串的处理上了。。 -7 被当成两个符号,用","隔开了。。。 
        # print(data_list)
        root = TreeNode(data_list.pop(0))
        queue = collections.deque([root])
        while queue:
            node = queue.popleft()
            if data_list: # 判断一下list里面还有没有值了。
                val = data_list.pop(0)  
                # print(val, val == 'null')   
                if val != 'null':
                    # print(val)
                    node.left = TreeNode(val)
                    queue.append(node.left) # put the node into the queue, so that next time it could be the root
            if data_list: # 判断一下list里面还有没有值了。
                val = data_list.pop(0)
                if val != 'null':
                    node.right = TreeNode(val)
                    queue.append(node.right)
        return root            

com

time: O(n) Spance: O(n)

biaohuazhou commented 2 years ago

思路

采用DFS方法 先序遍历整棵树 空节点也要用node代替 不然反序列化的时候 不知道是否为空 反序列化的时候 将字符串分隔放到栈里面 按照先序遍历 从栈中获取一个节点 dfs 采用递归实现

代码

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        return rserialize(root,"");
    }

    private String rserialize(TreeNode root, String s) {
        if(root==null){
            s+="Node,";
        }else{
            s+=s.valueOf(root.val)+",";
            //按照先序遍历 递归
            s=rserialize(root.left,s);
            s=rserialize(root.right,s);
        }
        return s;
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        //得到序列化的字符
        String[] split = data.split(",");
        Stack<String> stack = new Stack<>();
        for (int i = split.length-1; i >=0 ; i--) {
            stack.push(split[i]);
        }
        return rdeserialize(stack);
    }

    private TreeNode rdeserialize(Stack<String> stack) {
        if ("Node".equals(stack.peek())){
             stack.pop();
            return null;
        }
        String s = stack.pop();
        TreeNode root = new TreeNode(Integer.valueOf(s));
        root.left=rdeserialize(stack);
        root.right=rdeserialize(stack);
        return root;
    }
}

复杂度分析 时间复杂度: O(n) n为节点数 每个节点都需要运行 空间复杂度:O(n)开辟大小为n的栈

ghost commented 2 years ago
public class Codec {

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

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data == ""){
            return null;
        }
        String[] dataList = data.substring(1, data.length() - 1).split(",");
        TreeNode root = new TreeNode(Integer.parseInt(dataList[0]));
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int i = 1;
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            if(!"null".equals(dataList[i])){
                node.left = new TreeNode(Integer.parseInt(dataList[i]));
                queue.offer(node.left);
            }
            i++;
            if(!"null".equals(dataList[i])){
                node.right = new TreeNode(Integer.parseInt(dataList[i]));
                queue.offer(node.right);
            }
            i++;
        }
        return root;
    }
}
LinnSky commented 2 years ago

思路

iambigchen commented 2 years ago

思路

序列化: bfs,遇到空节点时,用#代替

反序列化: bfs,用两个指针分别指向左节点和右节点,每次遍历完一个节点后,左右指针都向后移动两步,而节点向后移动一步。此时左右指针指向的仍是当前节点的左右节点。

关键点

代码

JavaScript Code:


/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
const serialize = (root) => {
    const query = [root]
    let res = []
    while(query.length) {
        let node = query.shift()
        if (node) {
            res.push(node.val)
            query.push(node.left)
            query.push(node.right)
        } else {
            res.push('#')
        }
    }
    return res.join(',')
  };

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function(data) {
    if (data === '#') return null
    let list = data.split(',')
    let cur = 1
    let root = new TreeNode(list[0])
    const queue = [root];
    while(cur < list.length) {
        const node = queue.shift();
        const leftVal = list[cur];
        const rightVal = list[cur + 1];
        if (leftVal != "#") {
            const leftNode = new TreeNode(leftVal);
            node.left = leftNode;
            queue.push(leftNode);
        }
        if (rightVal != "#") {
            const rightNode = new TreeNode(rightVal);
            node.right = rightNode;
            queue.push(rightNode);
        }
        cur += 2
    }
    return root
};

/**
 * Your functions will be called as such:
 * deserialize(serialize(root));
 */

复杂度分析

令 n 为数组长度。

LannyX commented 2 years ago

思路

BFS 遍历,把遍历的结果转化成字符串 再递归反序列化

代码

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root == null){
            return "X,";
        }
        String left = serialize(root.left);
        String right = serialize(root.right);
        return root.val + "," + left + right;
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data == null) return null;
        Deque<String> nodes = new LinkedList<>();
        for(String s: data.split(",")){
            nodes.offer(s);
        }
        return rdeserialize(nodes);
    }
    public TreeNode rdeserialize(Deque<String> nodes){
        String every = nodes.poll();
        if(every.equals("X")) return null;
        TreeNode root = new TreeNode(Integer.parseInt(every));
        root.left = rdeserialize(nodes);
        root.right = rdeserialize(nodes);

        return root;
    }
}

复杂度分析

suukii commented 2 years ago

Link to LeetCode Problem

S1: BFS

要重构一棵二叉树的话,只要把原二叉树的结构记录下来就好了。

序列化时可以用层级遍历来记录树的结构,记得把空节点也记录下来。

反序列化时也是用层级遍历的方法一层一层地垒节点就好啦。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string res;
        if (!root) return res;

        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int len = q.size();
            while (len--) {
                TreeNode* node = q.front();
                if (node) {
                    res += to_string(node->val) + ',';
                    q.push(node->left);
                    q.push(node->right);
                } else {
                    res += "#,";
                }
                q.pop();
            }
        }
        return res;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if (data.empty()) return NULL;
        vector<string> dataArr;
        split(dataArr, data, ',');
        int i = 0;
        TreeNode* root = new TreeNode(stoi(dataArr[i++]));
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int len = q.size();
            while (len--) {
                TreeNode* node = q.front();
                q.pop();

                string leftVal = dataArr[i++];
                string rightVal = dataArr[i++];
                if (leftVal != "#") {
                    node->left = new TreeNode(stoi(leftVal));
                    q.push(node->left);
                }
                if (rightVal != "#") {
                    node->right = new TreeNode(stoi(rightVal));
                    q.push(node->right);
                }
            }
        }
        return root;
    }
    void split(vector<string>& list, const string& s, const char delimiter) {
        list.reserve(s.size());
        size_t start;
        size_t end = 0;
        while ((start = s.find_first_not_of(delimiter, end)) != string::npos) {
            end = s.find(delimiter, start);
            list.push_back(s.substr(start, end - start));
        }
        list.shrink_to_fit();
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function (root, emptyMarker = '#', seperator = ',') {
    if (!root) return '';

    const queue = [root];
    const arr = [];

    // BFS
    while (queue.length) {
        const node = queue.shift();

        if (node) {
            arr.push(node.val);
            // 子节点为空也要入列,因为要标记空节点
            queue.push(node.left, node.right);
        } else {
            // 标记空节点
            arr.push(emptyMarker);
        }
    }
    // 最后一层右侧的那些空节点标记可以删掉
    // 不删也行 `return arr.join(seperator);`
    return arr
        .join(seperator)
        .replace(new RegExp(`(${seperator}${emptyMarker})+$`), '');
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function (data, emptyMarker = '#', seperator = ',') {
    if (!data) return null;

    const nodes = data.split(seperator);
    const root = new TreeNode(nodes[0]);
    const queue = [root];

    let i = 1;
    // BFS
    while (queue.length) {
        const node = queue.shift();

        node.left = buildNode(nodes[i]);
        node.left && queue.push(node.left);
        i++;

        node.right = buildNode(nodes[i]);
        node.right && queue.push(node.right);
        i++;
    }

    return root;

    // *********************************
    function buildNode(value) {
        return value === void 0 || value === emptyMarker
            ? null
            : new TreeNode(value);
    }
};

/**
 * Your functions will be called as such:
 * deserialize(serialize(root));
 */

deserialize() 也可以用正则来读取节点值。

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function (data, emptyMarker = '#', seperator = ',') {
    const reg = new RegExp(`[^${seperator}]+`, 'g');
    let match = reg.exec(data);
    if (!match) return null;

    const root = new TreeNode(match[0]);
    const queue = [root];

    while (queue.length) {
        const node = queue.shift();

        match = reg.exec(data);
        if (!match) break;

        node.left = buildNode(match[0]);
        node.left && queue.push(node.left);

        match = reg.exec(data);
        if (!match) break;

        node.right = buildNode(match[0]);
        node.right && queue.push(node.right);
    }

    return root;

    // *********************************
    function buildNode(value) {
        return value === emptyMarker ? null : new TreeNode(value);
    }
};

serialize()

deserialize()

S2: DFS

这里用的是 preorder。

serialize

正常前序遍历即可,在遍历过程中组装字符串,遇到空节点加一个标识符。

deserialize

按前序遍历的顺序构建二叉树,也就是先构建当前节点,再递归构建左子树和右子树。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function (root, emptyMarker = '#', seperator = ',') {
    if (!root) return '';
    let str = '';
    preorder(root);
    // 删除最后的分隔符
    return str.slice(0, -1);

    // *******************************
    function preorder(root) {
        if (!root) {
            str += emptyMarker + seperator;
            return;
        }
        str += root.val + seperator;
        preorder(root.left);
        preorder(root.right);
    }
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function (data, emptyMarker = '#', seperator = ',') {
    if (!data) return null;
    const nodes = data.split(seperator);
    let i = 0;
    return preorder();

    // *********************************
    function preorder() {
        if (i >= nodes.length || nodes[i] === emptyMarker) return null;

        const node = new TreeNode(nodes[i]);
        i++;
        node.left = preorder();
        i++;
        node.right = preorder();

        return node;
    }
};

/**
 * Your functions will be called as such:
 * deserialize(serialize(root));
 */

serialize()

deserialize()

ZZRebas commented 2 years ago

思路

BFS,将一个二叉树的完全二叉树形式序列化,然后通过 BFS 反序列化,注意这并不是序列化成了完全二叉树,需做调整

代码(Python)

import collections
class TreeNode(object):
    def __init__(self,x):
        self.val=x
        self.left=None
        self.right=None

import collections
class Codec:
    def serialize(self,root):
        ans=''
        queue=[root]
        while queue:
            node=queue.pop(0)
            if node :
                ans+= str(node.val)+','
                queue.append(node.left)
                queue.append(node.right)
            else:
                ans+='null,'
        print(ans[:-1])
        return ans[:-1]

    def deserialize(self, data: str):
        if data == '#': return None
        nodes = data.split(',')
        if not nodes: return None
        root = TreeNode(nodes[0])
        queue = [root]
        # 已经有 root 了,因此从 1 开始
        i = 1

        while i < len(nodes) - 1:
            node = queue.pop(0)
            lv = nodes[i]
            rv = nodes[i + 1]
            i += 2
            if lv != '#':
                l = TreeNode(lv)
                node.left = l
                queue.append(l)

            if rv != '#':
                r = TreeNode(rv)
                node.right = r
                queue.append(r)
        return root

复杂度分析

Husky-Gong commented 2 years ago

Code

public class Codec {
    // 使用#来代表null的位置
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        // 因为是返回String 很自然想到使用StringBuilder
        StringBuilder sb = new StringBuilder();
        // 第二点就是选择遍历的方式,serialize和deserialize的遍历方式要一致就可以
        getSerialize(root, sb);

        return sb.toString();
    }

    private void getSerialize(TreeNode root, StringBuilder sb){
        if (root == null) {
            sb.append("#,");
            return;
        }
        // 采用preorder
        sb.append(root.val+"");
        sb.append(",");
        getSerialize(root.left, sb);
        getSerialize(root.right, sb);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        // 因为是使用#代表null,使用“,”来分隔
        // 考虑到可以从头部开始取值的只有LinkedList
        LinkedList<String> list = new LinkedList(Arrays.asList(data.split(",")));
        return buildTree(list);
    }

    private TreeNode buildTree(LinkedList<String> list){
        String temp = list.removeFirst();
        if (temp.equals("#")) {
            return null;
        }
        TreeNode root = new TreeNode(Integer.valueOf(temp));
        root.left = buildTree(list);
        root.right = buildTree(list);

        return root;
    }
}
tangjy149 commented 2 years ago

思路

根据示例,我联想到bfs可以完成序列化,与之前不同点在于null节点也需要进行表示
而反序列化其实就是bfs逻辑的逆推,弄两个队列q1和q2,q1是全部的序列化后的值,而q2用于存储树节点,先q1.pop(),q2.push(),保证下一个应该遍历的节点不丢失,然后每次从q2中弹出一个节点,对应从q1中也弹出两个left和right节点,是null则不加入q2,循环即可完成
而这一题另一个问题在于字符串的处理,我一开始是直接将当前数作为字符存入,而样例中存在多位数和负数,需要通过string来进行存储。对于字符串的处理,也是借鉴了其他的思路,编写了一个函数最终完成,这是我耗时最大的部分,因为自身对于字符串处理确实并不熟悉,需要提升

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    //split a string according to a separation character
    vector<string> split(const string & s, char sep){
        vector<string> strs;
        string tmp;
        for(auto ch:s){
            if(ch!=sep){
                tmp+=ch;
            }
            else{
                strs.emplace_back(tmp);
                tmp.clear();
            }
        }
        return strs;
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string ser="";
        if(root==nullptr) return ser;
        queue<TreeNode*> helper;
        helper.push(root);
        while(!helper.empty()){
            int len=helper.size();
            while(len--){
                TreeNode* temp=helper.front();
                ser+=(temp->val==1001?"#,":to_string(temp->val)+",");
                helper.pop();
                if(temp->val!=1001){
                    helper.push(temp->left==nullptr?new TreeNode(1001):temp->left);
                    helper.push(temp->right==nullptr?new TreeNode(1001):temp->right);
                }
            }
        }
        //cout<<ser<<endl;
        return ser;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data=="") return nullptr;
        queue<string> helper;
        queue<TreeNode*> tempQ;
        vector<string> nodes=split(data, ',');
        for(int i=0;i<nodes.size();i++){
            helper.push(nodes[i]);
        }
        TreeNode* cur=new TreeNode(atoi(nodes[0].c_str()));
        helper.pop();
        TreeNode* ans=cur;
        tempQ.push(cur);
        while(!helper.empty()){
            cur=tempQ.front();
            tempQ.pop();
            cur->left=helper.front()=="#"?nullptr:new TreeNode(atoi(helper.front().c_str()));
            if(cur->left!=nullptr) tempQ.push(cur->left);
            helper.pop();
            cur->right=helper.front()=="#"?nullptr:new TreeNode(atoi(helper.front().c_str()));
            if(cur->right!=nullptr) tempQ.push(cur->right);
            helper.pop();
        }
        return ans;

    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

复杂度

时间复杂度:O(n)
空间复杂度:O(n)(额外开辟了两个队列进行反序列化)

feifan-bai commented 2 years ago

思路

  1. DFS前序遍历,对于Null节点翻译成特殊符号
  2. 实现serialize函数,序列化左右子树
  3. deserialize反序列化结果 代码

    
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    from collections import deque
    class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        :type root: TreeNode
        :rtype: str
        """
        if not root: 
            return []
        q = deque()
        q.append(root)
        res = ''
        while q:
            node = q.popleft()
            if node != None:
                res += str(node.val) + ','
                q.append(node.left)
                q.append(node.right)
            else:
                res += 'X,'
        return res
    
    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        if not data: 
            return []
        data = data.split(',')
        root = TreeNode(data.pop(0))
        q = [root]
        while q:
            node = q.pop(0)
            if data:
                val = data.pop(0)
                if val != 'X':
                    node.left = TreeNode(val)
                    q.append(node.left)
            if data:
                val = data.pop(0)
                if val != 'X':
                    node.right = TreeNode(val)
                    q.append(node.right)

Your Codec object will be instantiated and called as such:

ser = Codec()

deser = Codec()

ans = deser.deserialize(ser.serialize(root))


*复杂度分析*
- 时间复杂度:O(N)
- 空间复杂度:O(N)
Richard-LYF commented 2 years ago

Definition for a binary tree node.

class TreeNode(object):

def init(self, x):

self.val = x

self.left = None

self.right = None

class Codec:

def serialize(self, root):
    """Encodes a tree to a single string.

    :type root: TreeNode
    :rtype: str
    """
    if not root:
        return 'None'
    return str(root.val)+','+str(self.serialize(root.left))+','+str(self.serialize(root.right))

def deserialize(self, data):
    """Decodes your encoded data to tree.

    :type data: str
    :rtype: TreeNode
    """
    def dfs(datalist):
        val = datalist.pop(0)
        if val=='None':
            return None
        root=TreeNode(int(val))
        root.left=dfs(datalist)
        root.right=dfs(datalist)
        return root

    return dfs(data.split(','))

Your Codec object will be instantiated and called as such:

ser = Codec()

deser = Codec()

ans = deser.deserialize(ser.serialize(root))

1149004121 commented 2 years ago

513. 找树左下角的值

思路

①深度优先
序列化:通过先序遍历,将结点都保存为字符串,形成形如“1,2,null,null,3,4,null,null,5,null,null” 的形式。
反序列化:将字符串通过“,”分割形成数组,第一个节点为根节点然后分别递归左子树和右子树。
②广度优先
序列化:通过层序遍历,将结点值一个个放入数组,然后通过join生成字符串。
反序列化:由三个指针分别指向该节点,该节点的左节点,该节点的右节点,第一个指针每次移动1,第二、三个指针每次移动2。

代码


    var serialize = function(root) {
        let str = ""
        function dfs(root){
            if(!root){
                str += `,null`;
                return;
            }
            str += `,${root.val}`;
            dfs(root.left);
            dfs(root.right);    
            return;
        }
        dfs(root);
        return str.slice(1);
    };
    var deserialize = function(data) {
        let arr = data.split(",");
        function dfs(arr){
            if(arr[0] === "null"){
                arr.shift();
                return null;
            }
            let root = new TreeNode(parseInt(arr[0]));
            arr.shift();
            root.left = dfs(arr);
            root.right = dfs(arr);
            return root;
        };
        return dfs(arr);
    };

    var serialize = function(root) {
        if(!root) return "null"
        let queue = [root];
        let res = [];
        while(queue.length){
            let node = queue.shift();
            if(node){
                res.push(node.val);
                queue.push(node.left);
                queue.push(node.right);
            }else{
                res.push("null");
            }
        }
        return res.join(",");
    };
    var deserialize = function(data) {
        if(data === "null") return null;
        let arr = data.split(",");
        let root = new TreeNode(+arr[0]);
        let queue = [root];
        let i = 0;
        while(i < arr.length - 2){
            let node = queue.shift();
            left = arr[i + 1];
            right = arr[i + 2];
            i += 2;
            if(left !== "null"){
                let ln = new TreeNode(+left);
                node.left = ln;
                queue.push(ln);
            };
            if(right !== "null"){
                let rn = new TreeNode(+right);
                node.right = rn;
                queue.push(rn);
            }
        }
        return root;
    };

复杂度分析

haixiaolu commented 2 years ago

思路: 参考NeetCode题解

DFS 前序遍历 (根节点 -> 左节点 -> 右节点)

代码 / Python


class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string."""

        res = []

        def dfs(node):
            if not node:
                res.append("N")
                return
            res.append(str(node.val))
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return ",".join(res)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """

        vals = data.split(",")
        self.i = 0

        def dfs():
            if vals[self.i] == "N":
                self.i += 1
                return None
            node = TreeNode(int(vals[self.i]))
            self.i += 1
            node.left = dfs()
            node.right = dfs()
            return node
        return dfs()

复杂度分析

zhiyuanpeng commented 2 years ago
class Codec:

    def sHelper(self, head, node_values):

        if head:
            node_values.append(str(head.val))
            self.sHelper(head.left, node_values)
            self.sHelper(head.right, node_values)
        else:
            node_values.append('None')

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        result = []
        if not root:
            return 'None'
        self.sHelper(root, result)
        return ','.join(result)

    def dHelper(self, l):
        if l[0] == 'None':
            l.popleft()
            return None
        root = TreeNode(int(l[0]))
        l.popleft()
        root.left = self.dHelper(l)
        root.right = self.dHelper(l)
        return root

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        # suppose we have a pre order str '1,2,3, None, None, 4, None, None, 5, None, None'
        l = deque(data.split(','))
        return self.dHelper(l)
qihang-dai commented 2 years ago

迭代前序遍历 + LinkedList递归反序列化


public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        StringBuilder sb = new StringBuilder();

        while(!stack.isEmpty()){
            TreeNode tmp = stack.pop();
            if(tmp != null){
                sb.append(tmp.val);
                sb.append(",");
                stack.push(tmp.right);
                stack.push(tmp.left);
            }else{
                sb.append("null");
                sb.append(",");
            }
        }

        return sb.toString();

    }
/* 主函数,将字符串反序列化为二叉树结构 */
TreeNode deserialize(String data) {
    // 将字符串转化成列表
    LinkedList<String> nodes = new LinkedList<>();
    for (String s : data.split(",")) {
        nodes.addLast(s);
    }
    return deserialize(nodes);
}

/* 辅助函数,通过 nodes 列表构造二叉树 */
TreeNode deserialize(LinkedList<String> nodes) {
    if (nodes.isEmpty()) return null;

    /****** 前序遍历位置 ******/
    // 列表最左侧就是根节点
    String first = nodes.removeFirst();
    if (first.equals("null")) return null;
    TreeNode root = new TreeNode(Integer.parseInt(first));
    /***********************/

    root.left = deserialize(nodes);
    root.right = deserialize(nodes);

    return root;
}
}
Zhang6260 commented 2 years ago

JAVA版本

使用BFS来进行序列化

public class Codec {
    public String serialize(TreeNode root) {
        //进行BFS遍历
        if(root==null)return "[]";
        Queue<TreeNode>queue=new LinkedList<TreeNode>();
        String res="[";
        TreeNode temp=null;
        queue.offer(root);
        while(!queue.isEmpty()){
            int size= queue.size();
            while(size>0){
                temp=queue.poll();
                if(temp!=null){
                     res=res+temp.val+",";
                    queue.offer(temp.left);
                    queue.offer(temp.right);
                }else{
                    res = res+"null,";
                }
                size--;
            }
        }
        //还有去掉最后的一个逗号
        res=res.substring(0,res.length()-1);
        res= res+"]";
        return res;
    }
    public TreeNode deserialize(String data) {
        //这样里去掉最前的【和 最后的】
        data = data.substring(1,data.length()-1);
        if(data.length()==0)return null;
        String src[]= data.split(",");
        TreeNode now_node=null,next_left=null,next_right=null;
        TreeNode res=new TreeNode(Integer.parseInt(src[0]));
        int num=src.length;
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.offer(res);
        int i=1;
        while(i<num-1){
            now_node=queue.poll();
            String lv=src[i];
            String rv=src[i+1];
            i+=2;
            if(!lv.equals("null")){
                next_left=new TreeNode(Integer.parseInt(lv));
                now_node.left =next_left;
                queue.offer(next_left);

            }
            if(!rv.equals("null")){
                next_right=new TreeNode(Integer.parseInt(rv));
                now_node.right=next_right;
                queue.offer(next_right);
            }
        }
        return res;
    }
}

时间复杂度:O(N)

空间复杂度:O(N)

Tesla-1i commented 2 years ago
class Codec:

    def serialize(self, root):
        if not root: return "None"
        left = self.serialize(root.left)
        right = self.serialize(root.right)
        return str(root.val) + "," + left + "," + right 

    def deserialize(self, data):
        data_list = data.split(",")

        def buildTree(data_list):
            val = data_list.pop(0)
            if val == "None":
                return None
            root = TreeNode(val)
            root.left = buildTree(data_list)
            root.right = buildTree(data_list)
            return root

        root = buildTree(data_list)
        return root
chengyufeng6 commented 2 years ago

class Codec { public:

// Encodes a tree to a single string.
string serialize(TreeNode* root) {
    if(root==nullptr){
        return "#";
    }
    return to_string(root->val) + ' ' + serialize(root->left) + ' ' + serialize(root->right);
}

TreeNode* mydeserialize(istringstream &ss ){
    string tmp;
    ss>>tmp;
    if(tmp=="#"){
        return nullptr;
    }
    TreeNode* node = new TreeNode(stoi(tmp));
    node->left = mydeserialize(ss);
    node->right = mydeserialize(ss);
    return node;
}

// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
    istringstream ss(data);
    return mydeserialize(ss);
}

};

zol013 commented 2 years ago
class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """

        def dfs(node, string):
            if not node:
                string += "None,"
                return string
            string += str(node.val) + ','
            string = dfs(node.left, string)
            string = dfs(node.right, string)

            return string

        return dfs(root, '')

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """

        def dfs(data_list):
            if data_list[0] == 'None':
                data_list.pop(0)
                return None

            root = TreeNode(int(data_list[0]))
            data_list.pop(0)
            root.left = dfs(data_list)
            root.right = dfs(data_list)
            return root

        data_list = data.split(',')
        return dfs(data_list)